LeetCode: Recover Binary Search Tree 解题报告
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 解题报告的更多相关文章
- 【LeetCode】99. Recover Binary Search Tree 解题报告(Python)
		
[LeetCode]99. Recover Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/p ...
 - LeetCode: Validate Binary Search Tree  解题报告
		
Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST) ...
 - 【LeetCode】109. Convert Sorted List to Binary Search Tree 解题报告(Python)
		
[LeetCode]109. Convert Sorted List to Binary Search Tree 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id ...
 - 【LeetCode】235. Lowest Common Ancestor of a Binary Search Tree 解题报告(Java & Python)
		
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 [LeetCode] https://leet ...
 - 【LeetCode】669. Trim a Binary Search Tree 解题报告(Python)
		
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...
 - 【LeetCode】98. Validate Binary Search Tree 解题报告(Python & C++ & Java)
		
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 BST的中序遍历是有序的 日期 题目地址:ht ...
 - 【LeetCode】501. Find Mode in Binary Search Tree 解题报告(Python)
		
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
 - 【LeetCode】701. Insert into a Binary Search Tree 解题报告(Python & C++)
		
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
 - 【LeetCode】700. Search in a Binary Search Tree 解题报告(Python)
		
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...
 
随机推荐
- QMessageBox的用法
			
QMessageBox的用法 先来看一下最熟悉的QMessageBox::information.我们在以前的代码中这样使用过: QMessageBox::information(NULL, ...
 - Coredata 单表简单使用
			
** 使用Coredata 工程中的DataModel创建:系统创建.手动创建** ** 使用Coredata需要要导入<CoreData/CoreData.h> ** 1.系统创建(系统 ...
 - AM335x启动
			
参考文件: 1.TI.Reference_Manual_1.pdf http://pan.baidu.com/s/1c1BJNtm 2.TI_AM335X.pdf http://pan.baidu.c ...
 - 潭州课堂25班:Ph201805201 并发(进程,线程)二   第十二课 (课堂笔记
			
线程与进程的其他相关操作 import threading # 线程 import multiprocessing # 进程 import socket import time def wo(): g ...
 - [NOI导刊2010提高]黑匣子
			
OJ题号:洛谷1801 思路:建立一个大根堆.一个小根堆.大根堆维护前i小的元素,小根堆维护当前剩下的元素. #include<cstdio> #include<queue> ...
 - Python不定参数函数
			
1. 元组形式 def test1(*args): print('################test1################') print(type(args)) print(arg ...
 - 喵哈哈村的魔法考试 Round #14 (Div.2) 题解
			
喵哈哈村的四月半活动(一) 题解: 唯一的case,就是两边长度一样的时候,第三边只有一种情况. #include <iostream> #include <cstdio> # ...
 - JAVA中String类常用方法 I
			
String类常用方法有: int length() -– 返回当前字符串的长度 int indexOf(int ch) -– 查找ch字符在该字符串中第一次出现的位置 int indexOf(Str ...
 - JProfiler远程监控
			
1. 服务端安装JProfiler(与客户端版本一致) 2. 客户端配置连接: A).session——integration wizards——New remote integration B) ...
 - iOS:用Block写一个链式编程
			
一.介绍 链式编程是一个比较新颖的编程方式,简单直观,用起来也比较舒服.目前比较有名的Mansory和BabyBlueTooth就是使用链式编程写的第三方框架. 二.写法 链式编程写法不同于传统方式, ...