Recover Binary Search Tree

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note:

A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.

Hide Tags Tree Depth-first Search

SOLUTION 1:

采用递归+全局变量完成:

空间复杂度是O(logn)

REF: http://huntfor.iteye.com/blog/2077665
这一篇讲得蛮清楚:
http://yucoding.blogspot.com/2013/03/leetcode-question-75-recover-binary.html

具体的思路,还是通过中序遍历,只不过,不需要存储每个节点,只需要存一个前驱即可。

例如1,4,3,2,5,6

1.当我们读到4的时候,发现是正序的,不做处理

2.但是遇到3时,发现逆序,将4存为第一个错误节点,3存为第二个错误节点

3.继续往后,发现3,2又是逆序了,那么将第2个错误节点更新为2

如果是这样的序列:1,4,3,5,6同上,得到逆序的两个节点为4和3。

========================================

这里我们补充一下,为什么要替换第二个节点而不是第一个节点:
e.g. The correct BST is below:


The inorder traversal is :  1 3 4 6 7 8 10 13
14

Find the place which the order is wrong.
       
Wrong order: 1 3 8 6 7 4 10 13
14

FIND:          
     
   8 6
       
Then we
find:     
   
   7 4
       
8, 6 是错误的序列, 但是,7,4也是错误的序列。
       
因为8,6前面的序列是正确的,所以8,6一定是后面的序列交换来的。
       
而后面的是比较大的数字,也就是说8一定是被交换过来的。而7,4
       
中也应该是小的数字4是前面交换过来的。

用反证法来证明:
       
假设:6是后面交换过来的
       
推论: 那么8比6还大,那么8应该也是后面交换来的,
       
这样起码有3个错误的数字了
       
而题目是2个错误的数字,得证,只应该是8是交换过来的。
结论就是:我们需要交换的是:8, 4.

  1. public class RecoverTree {
  2. TreeNode pre = null;
  3. TreeNode first = null;
  4. TreeNode second = null;
  5.  
  6. public void recoverTree(TreeNode root) {
  7. inOrder(root);
  8.  
  9. // swap the value of first and second node.
  10. int tmp = first.val;
  11. first.val = second.val;
  12. second.val = tmp;
  13. }
  14.  
  15. public void inOrder(TreeNode root) {
  16. if (root == null) {
  17. return;
  18. }
  19.  
  20. // inorder traverse.
  21. inOrder(root.left);
  22.  
  23. /*
  24. Find the place which the order is wrong.
  25. For example: 1 3 4 6 7 8 10 13 14
  26. Wrong order: 1 3 8 6 7 4 10 13 14
  27. FIND: ___
  28. Then we find: ___
  29. 8, 6 是错误的序列, 但是,7,4也是错误的序列。
  30. 因为8,6前面的序列是正确的,所以8,6一定是后面的序列交换来的。
  31. 而后面的是比较大的数字,也就是说8一定是被交换过来的。而7,4
  32. 中也应该是小的数字4是前面交换过来的。
  33.  
  34. 用反证法来证明:
  35. 假设:6是后面交换过来的
  36. 推论: 那么8比6还大,那么8应该也是后面交换来的,
  37. 这样起码有3个错误的数字了
  38. 而题目是2个错误的数字,得证,只应该是8是交换过来的。
  39. */
  40.  
  41. // 判断 pre 是否已经设置
  42. if (pre != null && pre.val > root.val) {
  43. if (first == null) {
  44. // 首次找到反序.
  45. first = pre;
  46. second = root;
  47. } else {
  48. // 第二次找到反序,更新Second.
  49. second = root;
  50. }
  51. }
  52.  
  53. pre = root;
  54.  
  55. // inorder traverse.
  56. inOrder(root.right);
  57. }

SOLUTION 2:

也可以采用非递归方法,不需要加全局变量,空间复杂度是O(logn):

  1. public void recoverTree1(TreeNode root) {
  2. if (root == null) {
  3. return;
  4. }
  5.  
  6. TreeNode node1 = null;
  7. TreeNode node2 = null;
  8.  
  9. TreeNode pre = null;
  10.  
  11. Stack<TreeNode> s = new Stack<TreeNode>();
  12. TreeNode cur = root;
  13.  
  14. while (true) {
  15. while (cur != null) {
  16. s.push(cur);
  17. cur = cur.left;
  18. }
  19.  
  20. if (s.isEmpty()) {
  21. break;
  22. }
  23.  
  24. TreeNode node = s.pop();
  25.  
  26. if (pre != null) {
  27. // invalid order
  28. if (pre.val > node.val) {
  29. if (node1 == null) {
  30. node1 = pre;
  31. node2 = node;
  32. } else {
  33. node2 = node;
  34. }
  35. }
  36. }
  37.  
  38. pre = node;
  39.  
  40. cur = node.right;
  41. }
  42.  
  43. int tmp = node1.val;
  44. node1.val = node2.val;
  45. node2.val = tmp;
  46.  
  47. return;
  48. }

SOLUTION 3:

还有更厉害的作法,可以达到O(1)的空间复杂度。以后再补上。

ref: http://fisherlei.blogspot.com/2012/12/leetcode-recover-binary-search-tree.html

=================

代码请参考主页君的实现:
请戳主页君的代码哦

LeetCode: Recover Binary Search Tree 解题报告的更多相关文章

  1. 【LeetCode】99. Recover Binary Search Tree 解题报告(Python)

    [LeetCode]99. Recover Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/p ...

  2. LeetCode: Validate Binary Search Tree 解题报告

    Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST) ...

  3. 【LeetCode】109. Convert Sorted List to Binary Search Tree 解题报告(Python)

    [LeetCode]109. Convert Sorted List to Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id ...

  4. 【LeetCode】235. Lowest Common Ancestor of a Binary Search Tree 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 [LeetCode] https://leet ...

  5. 【LeetCode】669. Trim a Binary Search Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...

  6. 【LeetCode】98. Validate Binary Search Tree 解题报告(Python & C++ & Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 BST的中序遍历是有序的 日期 题目地址:ht ...

  7. 【LeetCode】501. Find Mode in Binary Search Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  8. 【LeetCode】701. Insert into a Binary Search Tree 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  9. 【LeetCode】700. Search in a Binary Search Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...

随机推荐

  1. 洛谷 P1002 过河卒 【棋盘dp】

    题目链接:https://www.luogu.org/problemnew/show/P1002 题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点 ...

  2. python爬虫之分析Ajax请求抓取抓取今日头条街拍美图(七)

    python爬虫之分析Ajax请求抓取抓取今日头条街拍美图 一.分析网站 1.进入浏览器,搜索今日头条,在搜索栏搜索街拍,然后选择图集这一栏. 2.按F12打开开发者工具,刷新网页,这时网页回弹到综合 ...

  3. P1279 字串距离

    P1279 字串距离一看就是字符串dp,然而并不会,骗分之后爆零了.以后dp题要好好想想转移方程.f[i][j]表示是a串选了前i个字符,b串选了前j个字符的距离.显然(QAQ)f[i][j]=min ...

  4. ubuntu安装nodejs出现./config.gypi错误

    报错的内容如下: xxx@xxx [/usr/local/src/node-v0.8.3]# ./configure { 'target_defaults': { 'cflags': [], 'def ...

  5. C# 遍历控件 示例

    foreach(Control c in tabControl1.TabPages)//这个循环的意思是说,遍历tabControl1中所有的TabPages,TabPages是包含在tabContr ...

  6. CSDN 个性 博客 栏目 自定义 栏目 酷炫 音乐 视频

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 自定义 栏目 酷炫 音乐 视频 ========

  7. luogu P4178 Tree

    题目链接 luogu P4178 Tree 题解 点分治 代码 // luogu-judger-enable-o2 #include<cstdio> #include<algorit ...

  8. 4572: [Scoi2016]围棋 轮廓线DP KMP

    国际惯例的题面:这种题目显然DP了,看到M这么小显然要状压.然后就是具体怎么DP的问题.首先我们可以暴力状压上一行状态,然后逐行转移.复杂度n*3^m+3^(m*2),显然过不去. 考虑状态的特殊性, ...

  9. Codeforces Round #514 (Div. 2)

    目录 Codeforces 1059 A.Cashier B.Forgery C.Sequence Transformation D.Nature Reserve(二分) E.Split the Tr ...

  10. BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...