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.

 public class RecoverTree {
TreeNode pre = null;
TreeNode first = null;
TreeNode second = null; public void recoverTree(TreeNode root) {
inOrder(root); // swap the value of first and second node.
int tmp = first.val;
first.val = second.val;
second.val = tmp;
} public void inOrder(TreeNode root) {
if (root == null) {
return;
} // inorder traverse.
inOrder(root.left); /*
Find the place which the order is wrong.
For example: 1 3 4 6 7 8 10 13 14
Wrong order: 1 3 8 6 7 4 10 13 14
FIND: ___
Then we find: ___
8, 6 是错误的序列, 但是,7,4也是错误的序列。
因为8,6前面的序列是正确的,所以8,6一定是后面的序列交换来的。
而后面的是比较大的数字,也就是说8一定是被交换过来的。而7,4
中也应该是小的数字4是前面交换过来的。 用反证法来证明:
假设:6是后面交换过来的
推论: 那么8比6还大,那么8应该也是后面交换来的,
这样起码有3个错误的数字了
而题目是2个错误的数字,得证,只应该是8是交换过来的。
*/ // 判断 pre 是否已经设置
if (pre != null && pre.val > root.val) {
if (first == null) {
// 首次找到反序.
first = pre;
second = root;
} else {
// 第二次找到反序,更新Second.
second = root;
}
} pre = root; // inorder traverse.
inOrder(root.right);
}

SOLUTION 2:

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

 public void recoverTree1(TreeNode root) {
if (root == null) {
return;
} TreeNode node1 = null;
TreeNode node2 = null; TreeNode pre = null; Stack<TreeNode> s = new Stack<TreeNode>();
TreeNode cur = root; while (true) {
while (cur != null) {
s.push(cur);
cur = cur.left;
} if (s.isEmpty()) {
break;
} TreeNode node = s.pop(); if (pre != null) {
// invalid order
if (pre.val > node.val) {
if (node1 == null) {
node1 = pre;
node2 = node;
} else {
node2 = node;
}
}
} pre = node; cur = node.right;
} int tmp = node1.val;
node1.val = node2.val;
node2.val = tmp; return;
}

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. Linux系统之常用文件搜索命令

    (一)常用文件搜索命令 (1)which命令 (2)find命令 (3)locate (4)updatedb (5)grep (6)man (7)whatis (一)常用文件搜索命令 (1)which ...

  2. 前端解读面向切面编程(AOP)

    前言 面向对象(OOP)作为经典的设计范式,对于我们来说可谓无人不知,还记得我们入行起始时那句经典的总结吗-万事万物皆对象. 是的,基于OOP思想封装.继承.多态的特点,我们会自然而然的遵循模块化.组 ...

  3. sicp 习题

    1.11 求f(n)=f(n-1)+2*f(n-2)+3*f(n-3) #lang racket (define (fff n) (define (fff-iter a b c n) (if (= n ...

  4. bzoj 3924 点分

    感谢asm.Definer清楚明了的题解: http://www.cnblogs.com/Asm-Definer/p/4470112.html 收获: 1.  关于重心, 对于一个无向图, 我们这样给 ...

  5. BZOJ2759一个动态树好题 LCT

    题如其名啊 昨天晚上写了一发忘保存 只好今天又码一遍了 将题目中怕$p[i]$看做$i$的$father$ 可以发现每个联通块都是一个基环树 我们对每个基环删掉环上一条边 就可以得到一个森林了 可以用 ...

  6. Docker machine(Docker 虚拟机)

    安装docker [root@lianxi ~]# yum -y install docker 启动docker [root@lianxi ~]# systemctl start docker 下载D ...

  7. 跟着ZooKeeper学Java——CountDownLatch和Join的使用

    在阅读ZooKeeper的源码时,看到这么一个片段,在单机模式启动的时候,会调用下面的方法,根据zoo.cfg的配置启动单机版本的服务器: public void runFromConfig(Serv ...

  8. 10个提升MySQL性能的小技巧

    从工作量分析到索引的三条规则,这些专家见解肯定会让您的MySQL服务器尖叫. 在所有的关系数据库中,MySQL已经被证明了完全是一头野兽,只要通知停止运行就绝对不会让你多等一秒钟,使你的应用置于困境之 ...

  9. nginx多站路由配置tomcat

    server { listen 80; server_name 1.goal.cn; index index index.html index.htm index.jsp; root /www/ser ...

  10. [Android Pro] Android P版本 新功能介绍和兼容性处理(三)Android Studio 3.0 ~ 3.2 其他特性

    cp : https://blog.csdn.net/yi_master/article/details/80067198 1:JAVA8特性支持 1)Base64.java 在升级到as3.0之后, ...