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.

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

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

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

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

时间: 2024-08-23 07:03:18

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

【LeetCode】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? [解析] 题意:二叉搜索树中,有两个结点的位置

LeetCode: Validate Binary Search Tree 解题报告

Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key.The right subtree of a node co

[leetcode]Recover Binary Search Tree @ Python

原题地址:https://oj.leetcode.com/problems/recover-binary-search-tree/ 题意: Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. 解题思路:这题是说一颗二叉查找树中的某两个节点被错误的交换了,需要恢复成原来的正确的二叉查找树. 算法一:思路很简单,一颗二叉查

LeetCode: Recover Binary Search Tree

LeetCode: 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 s

LeetCode: Recover Binary Search Tree [099]

[题目] 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

LeetCode: Lowest Common Ancestor of a Binary Search Tree 解题报告

https://leetcode.com/submissions/detail/32662938/ Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between t

【LeetCode】Validate Binary Search Tree 解题报告

今天CSDN博客发生异常,折腾了大半天终于发出了这篇博文. [题目] Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a

LeetCode: Convert Sorted Array to Binary Search Tree 解题报告

Convert Sorted Array to Binary Search Tree Given an array where elements are sorted in ascending order, convert it to a height balanced BST.SOLUTION 1:使用递归解决. base case: 当索引值超过时,返回null. 递归主体:构造根节点,调用递归构造左右子树.并将左右子树挂在根节点上. 返回值:返回构造的根节点. GITHUB: https:

LeetCode 700 Search in a Binary Search Tree 解题报告

题目要求 Given the root node of a binary search tree (BST) and a value. You need to find the node in the BST that the node's value equals the given value. Return the subtree rooted with that node. If such node doesn't exist, you should return NULL. 题目分析及