https://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.
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
解题思路:
这道题的难点首先就在于,如何判断一个node的位置是错误的?
思考BST的定义,左子树的所有节点都<=root的值,右子树的所有节点都>root的值,并且所有子树也是这样。这是一个递归的定义。所以,就不能DFS的时候,仅仅判断当前节点是不是不比左节点小,并且比右节点小。这样的判断是无效的。
回想 Validate Binary Search Tree 这道题,我们能发现BST的一个重要性质——BST的inorder遍历结果,是单调递增的。那么如果一个BST有两个节点交换了位置,出来的结果一定有错误。但是,会有几处错误呢?
第一种情况,0,1,2这样的BST,变成了1,0,2,一处错误。
第二种情况,0,1,2,3,4,5,6,变成0,5,2,3,4,1,6。两处错误。
于是,思路是:inorder遍历BST,遇到当前节点val比前一个节点小的,说明出错了。第一种情况,当前节点和前一个节点换一下就可以了。第二种情况,第一个错误地方的前一个节点,和第二个错误地方的当前节点交换就可以了。
那么我们可以遇到第一次错误的时候,将前一个节点和当前节点都加入列表。后面出现错误,只要用当前节点去替换第二个位置就可以了。
代码如下:
/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public void recoverTree(TreeNode root) { List<TreeNode> list = new ArrayList<TreeNode>(); List<TreeNode> preList = new ArrayList<TreeNode>(); dfs(root, list, preList); TreeNode node1 = list.get(0); TreeNode node2 = list.get(1); int temp = node1.val; node1.val = node2.val; node2.val = temp; } public void dfs(TreeNode root, List<TreeNode> list, List<TreeNode> preList) { if(root == null) { return; } dfs(root.left, list, preList); if(preList.size() == 0) { preList.add(root); } else { if(root.val < preList.get(0).val) { if(list.size() == 0) { list.add(preList.get(0)); list.add(root); } else { list.set(1, root); //说明两个节点已经都找出来了,不要再递归下去了 return; } } preList.set(0, root); } dfs(root.right, list, preList); } }
这道题我没做出来,看的大神的结果。
http://blog.csdn.net/linhuanmars/article/details/24566995
原文:http://www.cnblogs.com/NickyYe/p/4456190.html