1、题目描述:


2、题解:

方法1:中序遍历迭代
二叉搜索树的性质:
1、若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
2、若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
3、任意节点的左、右子树也分别为二叉查找树;
4、没有键值相等的节点。
思路:

二叉搜索树的中序遍历是有序的
比如[4,2,3,1] 交换 4和1即可
代码精髓:
设置两个节点:第一个节点,是第一个按照中序遍历时前一个节点大于后一个节点,的前一个节点,即4第二个节点,是第一个节点找到后,再出现前一个节点大于后一个节点的,后一个节点,即1if not self.firstNode and self.pre.val >= root.val:self.firstNode = self.preif self.firstNode and self.pre.val >= root.val:self.secondNode = root
找到这两个节点后,交换节点值即可

Python代码如下:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:def recoverTree(self, root: TreeNode) -> None:"""Do not return anything, modify root in-place instead."""#中序遍历迭代firstNode = NonesecondNode = Nonepre = TreeNode(float('-inf'))stack = []p = rootwhile p or stack:while p:stack.append(p)p = p.leftp = stack.pop()if not firstNode and pre.val > p.val:firstNode = preif firstNode and pre.val > p.val:secondNode = ppre = pp = p.rightfirstNode.val,secondNode.val = secondNode.val,firstNode.val

方法2:中序遍历递归

思路:

二叉搜索树的中序遍历是有序的
比如[4,2,3,1] 交换 4和1即可
代码精髓:
设置两个节点:第一个节点,是第一个按照中序遍历时前一个节点大于后一个节点,的前一个节点,即4第二个节点,是第一个节点找到后,再出现前一个节点大于后一个节点的,后一个节点,即1
找到这两个节点,交换值即可

Python代码如下:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:def recoverTree(self, root: TreeNode) -> None:"""Do not return anything, modify root in-place instead."""# 中序遍历递归self.firstNode ,self.secondNode = None,Noneself.pre = TreeNode(float('-inf'))def in_order(root):if not root:returnin_order(root.left)if not self.firstNode and self.pre.val >= root.val:self.firstNode = self.preif self.firstNode and self.pre.val >= root.val:self.secondNode = rootself.pre = rootin_order(root.right)in_order(root)self.firstNode.val,self.secondNode.val = self.secondNode.val,self.firstNode.val

方法3:Morris中序遍历

可以参考力扣94题
面试算法:二叉树的Morris遍历算法

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:def recoverTree(self, root: TreeNode) -> None:"""Do not return anything, modify root in-place instead."""# Morris中序遍历firstNode,secondNode = None,Nonepre = TreeNode(float('-inf'))cur = rootwhile cur:if not cur.left:if not firstNode and pre.val >= cur.val:firstNode = preif firstNode and pre.val >= cur.val:secondNode = curpre = curcur = cur.rightelse:#找左子树的最右边的节点temp = cur.leftwhile temp.right and temp.right != cur:temp = temp.rightif not temp.right:temp.right = curcur = cur.leftif temp.right == cur:temp.right = Noneif not firstNode and pre.val >= cur.val:firstNode = preif firstNode and pre.val >= cur.val:secondNode = curpre = curcur = cur.rightfirstNode.val ,secondNode.val = secondNode.val,firstNode.val

3、复杂度分析:

方法1:
时间复杂度:O(N),N为结点的个数
空间复杂度:O(H),H为二叉树的深度
方法2:
时间复杂度:O(N),N为结点的个数
空间复杂度:O(H),H为二叉树的深度
方法3:
时间复杂度:O(N)
空间复杂度:O(1)

深度优先搜索DFS | Morris遍历:力扣99. 恢复二叉搜索树相关推荐

  1. LeetCode 98验证二叉搜素树(中序遍历)99恢复二叉搜索树

    微信搜一搜:bigsai 大家都在关注的刷题.学习数据结构和算法宝藏项目 关注回复进群即可加入力扣打卡群,欢迎划水.近期打卡: LeetCode 92反转链表Ⅱ&93复制ip地址&94 ...

  2. 72. Leetcode 99. 恢复二叉搜索树 (二叉搜索树-中序遍历类)

    给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换.请在不改变其结构的情况下,恢复这棵树 .示例 1:输入:root = [1,3,null,null,2] 输出:[3,1, ...

  3. 力扣题目——235. 二叉搜索树的最近公共祖先

    注:本文的代码实现使用的是 JS(JavaScript),为前端中想使用JS练习算法和数据结构的小伙伴提供解题思路.( 描述 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 最近公共祖先 ...

  4. LeetCode 力扣 538. 把二叉搜索树转换为累加树 convertBstToGreaterTree538树

    大家觉得写还可以,可以点赞.收藏.关注一下吧! 也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn 文章目录 538. 把二叉搜索树转换为累 ...

  5. 力扣538.把二叉搜索树转换为累加树

    题目来源: 538.把二叉搜索树转换为累加树 题目: 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中 ...

  6. 99. 恢复二叉搜索树

    root 是一棵错误的二叉搜索树(有2个节点被错误交换) 发生在逆序对的头,尾这两个位置 第2个错误节点:最后一个逆序对中较小的那个节点 second /*** Definition for a bi ...

  7. LeetCode 99. 恢复二叉搜索树(中序遍历)

    1. 题目 二叉搜索树中的两个节点被错误地交换. 请在不改变其结构的情况下,恢复这棵树. 你能想出一个只使用常数空间的解决方案吗? 2. 解题 循环中序遍历(栈),记录不满足的节点,交换其val O( ...

  8. 力扣98. 验证二叉搜索树(JavaScript)

    var isValidBST = function(root) {//按中序保存到数组中,则数组应该是从小到大的升序let arr=[]const dd=function(root){if(root! ...

  9. 力扣669. 修剪二叉搜索树(JavaScript)

    var trimBST = function(root, low, high) {if(root==null){return root}//判断当前节点是否小于lowif(root.val<lo ...

最新文章

  1. R语言普通最小二乘(OLS)回归说明、以及构建普通最小二乘(OLS)回归需要满足的四个假设(Normality(正态性)、Independence(独立性)、Linearity(线性度)、方差齐性)
  2. rk3399 采集摄像头数据_[Camera]摄像头镜像
  3. Mac 终端便利工具: 管理工具-Homebrew 和提示工具oh my zsh
  4. matlab中gui关闭图像直方图,07年写的,直方图 matlab gui
  5. 【收藏】使用Docker搭建MySQL服务
  6. 安卓qpythonttsspeak_当python遇到Android手机 那么,万物皆可盘
  7. 构建之法阅读笔记之三
  8. 确保移动设备的安全:在保护数据的同时提高工作效率
  9. 【树莓派搭建个人网站】WordPress安装
  10. mysql5.6主从复制与基于amoeba实现读写分离
  11. 从零学React Native之05混合开发
  12. 【见闻录系列】浅谈搜索系统与推荐系统的一点区别
  13. springboot+vue疫情管理大作业
  14. Ie8兼容性问题web.config设置
  15. 如何让图片保持原比例,占满整个盒子
  16. win10如何安装多个jdk并实时进行切换【建议收藏】
  17. Objective-C(八、正式协议Protocol,非正式协议informal protocol)——iOS开发基础
  18. 验证手机号是否注册过爱奇艺
  19. 安卓加密软件_【winhex/Xways实战应用】安卓QQ卸载后的手工恢复实战
  20. 模块与模块之间通信设计-组件设计思想

热门文章

  1. 软件测试面试题:什么是数据的对立性,有几个层次?
  2. 解决uniapp微信开发小程序背景本地图片渲染层网络层错误问题
  3. 图片路径前缀有blob?图片渲染不出来?
  4. 【西门子案例】西门子1200PLC 传送带控制升级版
  5. 千里送人头  ——APIO2017 游记
  6. Vue3 - filters 过滤器为什么被移除放弃?取而代之的解决方案又是什么?
  7. 远程桌面进去服务器的办法,远程重启服务器后没法链接远程桌面解决办法
  8. FOTA与OTA区别在哪?
  9. 平安好医生和智慧教育的AI(语音)技术应用
  10. pycharm报错SyntaxError: Non-UTF-8 code starting with ‘\xdf‘ in file的一种可能的解决方式