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