力扣每日一题99:恢复二叉搜索树

题目

给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 

示例 1:

输入:root = [1,3,null,null,2]
输出:[3,1,null,null,2]
解释:3 不能是 1 的左孩子,因为 3 > 1 。交换 1 和 3 使二叉搜索树有效。

示例 2:

输入:root = [3,1,4,null,null,2]
输出:[2,1,4,null,null,3]
解释:2 不能在 3 的右子树中,因为 2 < 3 。交换 2 和 3 使二叉搜索树有效。

提示:

  • 树上节点的数目在范围 [2, 1000] 内
  • -231 <= Node.val <= 231 - 1

进阶:使用 O(n) 空间复杂度的解法很容易实现。你能想出一个只使用 O(1) 空间的解决方案吗?

通过次数

146.4K

提交次数

242.3K

通过率

60.5%

分析

二叉搜索树中序遍历是有序的(a[i]<a[i+1]),错误交换两个节点后,存在两个地方(a[i]>a[i+1]),如果两个地方重复了,那就是一个地方。

所以我们只要根据a[i]>a[i+1]这一特性找的错误交换的两个点换回来就行了。

普通方法:设置数组存放数据。时间O(N),空间O(N)

中序遍历依次二叉树,同时将每个节点的地址和值分别放在一个数组里。然后再遍历记录数值的数组,找到要交换的两个位置。

class Solution {
public:void dfs(int arr[],TreeNode* adress[],int &pos,TreeNode* root){if(!root) return;dfs(arr,adress,pos,root->left);arr[pos]=root->val;adress[pos]=root;pos++;dfs(arr,adress,pos,root->right);}void recoverTree(TreeNode* root) {TreeNode *adress[1000];int arr[1000];int pos=0;dfs(arr,adress,pos,root);int t1=-1,t2=0;for(int i=0;i<pos-1;i++){//cout<<arr[i]<<",";if(arr[i]>arr[i+1]){if(t1==-1){t1=i;t2=i+1;}else t2=i+1;}}//cout<<arr[pos-1];//cout<<"\nt1="<<t1<<"   t2="<<t2;int t=adress[t1]->val;adress[t1]->val=adress[t2]->val;adress[t2]->val=t;}
};

进阶:中序遍历,栈记录前驱。时间O(N),空间(H),H为树的高度。

前面的方法是找到要交换连个节点的地址,然后交换值。我们用了一个数组记录所有节点的地址。其实我们就交换两个数,记录两个地址就行了。用二叉树的迭代法遍历可以用栈存放遍历的前驱,刚好符合了i和i+1的关系。下面是官方题解。

class Solution {
public:void recoverTree(TreeNode* root) {stack<TreeNode*> stk;TreeNode* x = nullptr;TreeNode* y = nullptr;TreeNode* pred = nullptr;while (!stk.empty() || root != nullptr) {while (root != nullptr) {stk.push(root);root = root->left;}root = stk.top();stk.pop();if (pred != nullptr && root->val < pred->val) {y = root;if (x == nullptr) {x = pred;}else break;}pred = root;root = root->right;}swap(x->val, y->val);}
};

高阶:Morris遍历,时间O(N),空间O(1)

废话不多说,看官方题解的代码。

class Solution {
public:void recoverTree(TreeNode* root) {TreeNode *x = nullptr, *y = nullptr, *pred = nullptr, *predecessor = nullptr;while (root != nullptr) {if (root->left != nullptr) {// predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止predecessor = root->left;while (predecessor->right != nullptr && predecessor->right != root) {predecessor = predecessor->right;}// 让 predecessor 的右指针指向 root,继续遍历左子树if (predecessor->right == nullptr) {predecessor->right = root;root = root->left;}// 说明左子树已经访问完了,我们需要断开链接else {if (pred != nullptr && root->val < pred->val) {y = root;if (x == nullptr) {x = pred;}}pred = root;predecessor->right = nullptr;root = root->right;}}// 如果没有左孩子,则直接访问右孩子else {if (pred != nullptr && root->val < pred->val) {y = root;if (x == nullptr) {x = pred;}}pred = root;root = root->right;}}swap(x->val, y->val);}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/594479.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【linux】ufw 的基本使用

碎碎念 所有的云平台的网络流量的进出基本上有三层&#xff0c;首先是虚拟网的流量控制&#xff0c;一般是通过子网访问控制列表来控制vpc也好子网也好的流量出入&#xff0c;其次是安全组控制一层&#xff0c;通过安全组规则控制一类/一组主机&#xff08;指EC2/ECS/VM/CE这些…

c语言结构体学习

文章目录 前言一、结构体的声明1&#xff0c;什么叫结构体?2&#xff0c;结构体的类型3,结构体变量的创建和初始化4&#xff0c;结构体的类型5&#xff0c;结构体的初始化 二、结构体的访问1&#xff0c;结构体成员的点操作符访问2&#xff0c;结构体体成员的指针访问 三、结构…

rime中州韵小狼毫 inputShow lua Filter 输入字符透传滤镜

在 rime中州韵小狼毫 inputShow lua Translator 一文中&#xff0c;我们通过 inputShow.lua 定制了 inputShow_translator&#xff0c;这使得我们的输入方案可以将用户输入的字符透传到候选列表中来。如下&#x1f447;&#xff1a; &#x1f446;上图中我们在候选列表中看到了…

蓝桥杯python比赛历届真题99道经典练习题 (89-99)

【程序89】 题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。 1.程序分析: 2.程序源代码: from sys import stdout if __n…

基于ssm+vue服装商城购物系统

摘要 在基于SSM框架和Vue.js的服装商城购物系统中&#xff0c;整合了多种先进的技术&#xff0c;为电子商务领域的发展提供了有力支持。该系统不仅仅是技术层面的整合&#xff0c;更是对于业务流程和用户体验的深入考虑。以下是对该系统扩展的一些关键方面的讨论&#xff0c;以…

Python API接口开发用法介绍

API&#xff08;Application Programming Interface&#xff09;是应用程序接口的简称&#xff0c;是一种使得不同软件之间进行互操作的定义和协议。Python API接口开发&#xff0c;简单来说&#xff0c;就是使用Python语言进行软件接口的开发&#xff0c;使得不同程序间可以互…

synchronized锁

synchronized 类锁&#xff1a;给类的静态方法加上synchronized 关键字进行修饰&#xff0c; 锁的是当前类class&#xff0c;一个静态同步方法拿到锁&#xff0c;其他静态同步方法就会等待静态同步方法和普通同步方法间是没有竞争的 对象锁&#xff1a;给类的方法加上synchron…

elasticsearch如何操作索引库里面的文档

上节介绍了索引库的CRUD&#xff0c;接下来操作索引库里面的文档 目录 一、添加文档 二、查询文档 三、删除文档 四、修改文档 一、添加文档 新增文档的DSL语法如下 POST /索引库名/_doc/文档id(不加id,es会自动生成) { "字段1":"值1", "字段2&q…

Bytebase 2.13.0 - 支持 StarRocks

&#x1f680; 新功能 支持 StarRocks。支持 PostgreSQL, Redshift, RisingWave 高级自动补全。 &#x1f384; 改进 支持在 SQL 编辑器的表结构 DDL 弹窗中展示 index 语句。支持在 SQL 编辑器中查询 PostgreSQL 外部表。汉化钉钉 webhook 消息。 &#x1f3a0; 社区 视频…

基于头脑风暴算法优化的Elman神经网络数据预测 - 附代码

基于头脑风暴算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于头脑风暴算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于头脑风暴优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&…

Vue3 的 emit 该怎么写, vue2 对比

Vue3 的 emit 该怎么写&#xff0c; vue2 对比 这是个新手问题&#xff0c;从 vue2 转到 vue3 之后&#xff0c;一时间不知道该怎么用它了。 vue2 用法 vue2 在 template 中 和 在方法中的用法如下&#xff1a; <template><button click"$emit(clicked, 要传…

Scrum敏捷认证CSM官方认证班Certified ScrumMaster - CSM认证班

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架&#xff0c;旨在最短时间内交付最大价值。根据2021年全球敏捷状态报告&#xff0c;Scrum及Scrum衍生方法的应用占比达到81%。 在企业的敏捷转型历程中&#xff0c;Scru…

【Python机器学习】衡量模型是否成功:训练数据测试数据

在机器学习中&#xff0c;为了衡量模型是否成功&#xff0c;通常做法是吧将收集好的带标签数据分成两部分&#xff0c;一部分用于构建机器学习模型&#xff0c;叫做训练数据或训练集&#xff1b;其余数据用来评估模型性能&#xff0c;叫做测试数据、测试集或者留出集。 scikit…

贝锐花生壳全新功能:浏览器一键远程访问SSHRDP远程桌面

为了满足特定场景的远程访问需求&#xff0c;如&#xff1a;远程群晖NAS设备、远程SQL Server数据库/MySQL数据库、3389远程桌面&#xff08;RDP远程桌面&#xff09;、远程SSH、我的世界游戏联机…… 贝锐花生壳推出了场景映射服务&#xff0c;不仅提供满足相应场景的网络带宽…

4.Unity中向量相关

向量 //三维向量 - Vector3 //Vector3有两种几何意义 //1.位置 -- 代表一个点 print(this.transform.position);//2.方向 -- 代表一个方向 print(this.transform.forward); print(this.transform.up); 两点决定一个向量 //A和B此时 几何意义 是两个点Vector3 A new Vector3(…

在 2024 年搜索中提升排名的 7 项内容调整

忘掉关键词填充和算法追逐。2024 年的重点是 EEAT&#xff0c;宝贝&#xff01;谷歌希望最专业、最权威、最值得信赖&#xff08;EEAT&#xff09;的内容能够排名靠前&#xff0c;这就意味着您的内容需要成为专业知识、参与度和信任度的交响乐。 准备好让搜索引擎和人类都无法…

19. Mysql 循环语句

文章目录 概念循环语句while 循环语句repeat 循环语句loop 循环语句iterate 和 leave 语句 精选示例总结参考资料 概念 循环结构是编程中常见的控制结构&#xff0c;它允许我们重复执行一段代码&#xff0c;直到满足特定条件为止。 在 Mysql 中&#xff0c;常用来实现各种复杂…

YOLOv5算法进阶改进(10)— 更换主干网络之MobileViTv3 | 轻量化Backbone

前言:Hello大家好,我是小哥谈。MobileViTv3是一种改进的模型架构,用于图像分类任务。它是在MobileViTv1和MobileViTv2的基础上进行改进的,通过引入新的模块和优化网络结构来提高性能。本节课就给大家介绍一下如何在主干网络中引入MobileViTv3网络结构,希望大家学习之后能够…

基于Java SSM框架实现四六级在线考试系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现四六级在线考试系统演示 摘要 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多学院的之中&#xff0c;随之就产生了“四六级在线考试系统”&#xff0c;这样就让四六级在线考试系统更加方便…

基于SpringBoot的汽车资讯网站

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的汽车资讯网站,java项目…