【LeetCode】Recover Binary Search Tree

133 篇文章 0 订阅
121 篇文章 2 订阅
Recover Binary Search Tree 
Total Accepted: 7163 Total Submissions: 31922 My Submissions
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?
考察的应该是中序遍历,如果二叉搜索树正确并且不包含重复数据,那么中序遍历的结果应该是递增序列。
假设有一个中序遍历结果是这样的:
1, 2, 3, 4, 5, 6, 7
如果2和7交换,结果如下:
1, 7, 3, 4, 5, 6, 2
按照中序遍历,找到第一个7->3,发现3比它的前驱7小,那么第一个找到的是7,也就是说第一步找到的是大数。那么下一步找到的应该就是二者当中的小数,继续扫描,发现6->2,取小,应该就是2。
还有一种,就是相邻的两个节点交换:
1, 2, 4, 3, 5, 6, 7
找到4和3交换,这也是为什么在找到第一对有错的数之后,将小数赋值给sec的原因。
关于这一段理解,在讨论结果 http://discuss.leetcode.com/questions/272/recover-binary-search-tree有一段英文,写的非常好,也很明白,如下,供参考。

/* This is an easy problem, but made difficult because you can only use O(1) space.
 * Traverse the tree using inorder. Its easy to spot nodes that are out of place: 
 * They will not be in increasing order
 * In order to accomplish this, we need to do an in order traverse and keep track of 
 * the previous node. The first time previous is larger than the current node (root),
 * both previous and root must be added because both could potentially be in violation. 
 * If however we find another violation (i.e. previous is greater than current), 
 * then we can replace the last value of the node array with the current (root) node. 
 * Why? Because two nodes have been swapped. We find the larger of the two first 
 * (because of the in order traversal), so the next node must be smaller of the two.
 *
 * Space: O(1) - only an array of size 2
 * Time Complexity: O(n), where n is the number of nodes 
 * (i.e. complexity of in-order traversal)
 */

Java AC

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    private TreeNode first;
    private TreeNode sec;
    private TreeNode pre;
    public void recoverTree(TreeNode root) {
        first = null;
        sec = null;
        pre = null;
        findError(root);
        if(first != null && sec != null){
            int temp = sec.val;
            sec.val = first.val;
            first.val = temp;
        }
    }
    private void findError(TreeNode root){
        if(root == null){
            return;
        }
        findError(root.left);
        if(pre != null && root.val < pre.val){
            if(first == null){
                first = pre;
                sec = root;
            }else{
                sec = root;
                return;
            }
        }
        pre = root;
        findError(root.right);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值