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?


题中提到,有两个点是被错误地swapped了。那么如果想要实现空间复杂度O(1)的算法,一个可行的方法就是找出这两个出错的点,然后把它们的值swap回来就可以了。

先看代码:

public class Solution {
    private TreeNode firstAbnor = null;
    private TreeNode secondAbnor = null;
    private TreeNode lastNode = new TreeNode(Integer.MIN_VALUE);
 
    public void recoverTreeHelper(TreeNode root) {
        if(root == null) {
            return;
        }
        
        recoverTreeHelper(root.left);
        
        if (firstAbnor == null && root.val < lastNode.val) {
            firstAbnor = lastNode;
        }
        
        if (firstAbnor != null && root.val < lastNode.val) {
            secondAbnor = root;
        }
        
        lastNode = root;
        
        recoverTreeHelper(root.right);
    }
    
    
    public void recoverTree(TreeNode root) {
        recoverTreeHelper(root);
       
        int tmp = firstAbnor.val;
        firstAbnor.val = secondAbnor.val;
        secondAbnor.val = tmp;  
    }
}


首先看public void recoverTreeHelper(TreeNode root) 这个 helper function。这个方程的功能就是找到上面说的那两个出错的点。

对于这个方程,如果抛去其他的部分不看,可以抽象为如下这些:

public void recoverTreeHelper(TreeNode root) {
        if(root == null) {
            return;
        }
        
        recoverTreeHelper(root.left);
        // ... do something
        lastNode = root;
        
        recoverTreeHelper(root.right);
    }

这么一看就很明朗了,这就是一个递归的树的中序遍历。中序遍历是保证遍历的值是递增的。

那么如果在遍历的过程中碰上不符合递增顺序的,显然就是出错的值。这就是那两个 if() 判断语句的职责,判断出不符合递增的点,记录在firstAbnor和secondAbnor里,对应找到的两个不符合顺序的点。


lastNode就跟前一篇文章 flatten中的方法一样,记录的其实就是在中序遍历中,当前访问节点的之前一次访问的节点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值