【问题描述】[困难]

【解答思路】

1. 显示中序遍历

时间复杂度:O(N) 空间复杂度:O(N)

class Solution {public void recoverTree(TreeNode root) {List<Integer> nums = new ArrayList<Integer>();inorder(root, nums);int[] swapped = findTwoSwapped(nums);recover(root, 2, swapped[0], swapped[1]);}public void inorder(TreeNode root, List<Integer> nums) {if (root == null) {return;}inorder(root.left, nums);nums.add(root.val);inorder(root.right, nums);}public int[] findTwoSwapped(List<Integer> nums) {int n = nums.size();//第一次找到取前面 第二次找到取后面int x = -1, y = -1;for (int i = 0; i < n - 1; ++i) {if (nums.get(i + 1) < nums.get(i)) {y = nums.get(i + 1);if (x == -1) {x = nums.get(i);} else {break;}}}return new int[]{x, y};}public void recover(TreeNode root, int count, int x, int y) {if (root != null) {if (root.val == x || root.val == y) {root.val = root.val == x ? y : x;if (--count == 0) {return;}}recover(root.right, count, x, y);recover(root.left, count, x, y);}}
}
2. 隐式中序遍历 栈


时间复杂度:O(N) 空间复杂度:O(H)

class Solution {public void recoverTree(TreeNode root) {Deque<TreeNode> stack = new ArrayDeque<TreeNode>();TreeNode x = null, y = null, pred = null;while (!stack.isEmpty() || root != null) {while (root != null) {stack.push(root);root = root.left;}root = stack.pop();if (pred != null && root.val < pred.val) {y = root;if (x == null) {x = pred;} else {break;}}pred = root;root = root.right;}swap(x, y);}public void swap(TreeNode x, TreeNode y) {int tmp = x.val;x.val = y.val;y.val = tmp;}
}
3. Morris 中序遍历





时间复杂度:O(N) 空间复杂度:O(1)

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

【总结】

1. 交换的思想

两个指针或两个标志找逆序

2. 二叉搜索树 中序遍历 单调递增
3.空间复杂度优化 Morris 中序遍历优化 空间复杂度:O(1)

转载链接:https://leetcode-cn.com/problems/recover-binary-search-tree/solution/hui-fu-er-cha-sou-suo-shu-by-leetcode-solution/

[Leetcode][第99题][JAVA][恢复二叉搜索树][中序遍历]相关推荐

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

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

  2. 74. Leetcode 501. 二叉搜索树中的众数 (二叉搜索树-中序遍历类)

    给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素).如果树中有不止一个众数,可以按 任意顺序 返回.假定 BST 满足如下定义:结 ...

  3. 73. Leetcode 230. 二叉搜索树中第K小的元素 (二叉搜索树-中序遍历类)

    给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数).示例 1:输入:root = [3,1,4,null,2], k = 1 输出 ...

  4. 49 - 算法 - 二叉树 - leetcode108.-将有序数组转换为二叉搜索树-中序遍历 - vector

    //vec 构造函数 vec.begin() end() + num ={134} =other vector //一直到null 就行 new(int) root->left ->rig ...

  5. 【剑指offer-Java版】24二叉搜索树后序遍历序列

    二叉搜索树的后续遍历序列:既然是二叉搜索树,那么就满足左子树结点都大于或者小于根节点右子树都小于或大于根结点 根据搜索树的这种特点,将给定的树划分为左子树或者右子树,递归的处理左右子树 public ...

  6. HDOJ-3999(二叉搜索树+先序遍历)

    The order of a Tree 题解:先建立一颗二叉搜索树,然后先序遍历 示例图 import java.util.Scanner;public class Main3 {public sta ...

  7. 《LeetCode力扣练习》第96题 不同的二叉搜索树 Java

    <LeetCode力扣练习>第96题 不同的二叉搜索树 Java 一.资源 题目: 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回 ...

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

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

  9. LeetCode刷题笔记 二叉树 二叉搜索树的操作

    669 修剪二叉搜索树 ​ 给定一个二叉查找树和两个整数 L 和 R,且 L < R,试修剪此二叉查找树,使得修剪后所有节点的值都在 [L, R] 的范围内. ​ 输入是一个二叉查找树和两个整数 ...

最新文章

  1. 梯度下降优化算法综述与PyTorch实现源码剖析
  2. PS切图篇(一)---界面设置
  3. php display_errors
  4. 《『若水新闻』客户端开发教程》——20.程序打包发布
  5. 4)公有成员\私有成员和静态成员
  6. 深度解析算法优化内部机制:为什么机器学习算法难以优化?
  7. 解决Button在IE6、7下的自适应宽度问题
  8. OS酱:“哎呀内存太小了,人家又缺页了!”
  9. java代码连接redis_java代码连接redis
  10. word导入mysql表格_数据插入Word 表格步骤
  11. AcWing之找出数组中重复的数字
  12. 谷歌AI用“深度”学习来虚化背景,单摄手机可用,Jeff Dean表示优秀
  13. mysql安装运行(centos)
  14. 把后端传递过来的base64图片保存到本地
  15. 这个“达芬奇”不一般!它是美国医生的好帮手
  16. Java11完全兼容Java8吗_Java11正式发布,要不要升级请看这里!
  17. 手机无线连接到电脑共享文件
  18. 管制条目的地DDS文件生成器,ATC3版
  19. Python基础(七) | 文件、异常以及模块详解
  20. freertos认识(freertos篇-1)

热门文章

  1. Hadoop生态系统学习路线
  2. 微信小程序 三元运算 checked
  3. 2015.5.12站立会议
  4. windows phone (12) 小试自定义样式
  5. linux3.0.4编译LDD中的scull全过程
  6. linux 命令行模式下,浏览网页方法
  7. ajax modelbinder,.NET Core 使用ModelBinder去掉所有参数的空格
  8. maven 关于使用 snapshot 的坑
  9. Android list转xml
  10. Android自定义view详解,使用实例,自定义属性,贝塞尔曲线