recover-binary-search-tree && validate-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?

题目很简单,就是一个二叉搜索树,其中有两个节点被调换了,需要恢复过来。
可以直接修改节点的value,而不需要移动节点。

如果对二叉搜索树的结构和遍历过程不熟悉,会觉得有点不好下手。
其实稍微理一下还是比较简单的,思路过程如下:

  • 二叉搜索树,中序遍历取节点value时,得到的是一个有序(升序)的数组;
  • 交换了两个节点,实际上在中序遍历取value得到数组中,数组会出现两个异常的值(与相邻值对比不满足升序);
  • 这两个异常值所对应的节点也就是被调换的节点;
  • 把这两个节点的值进行替换则可恢复成原来的二叉搜索树。

例如某个二叉搜索树中序遍历取value后得到的数组是:
1,2,3,4,5,6,7,8,9
现在交换3和7所在的节点,再次中序遍历取value后得到的数组是:
1,2,7,4,5,6,3,8,9
通过中序遍历很容易得到此二叉搜索树的异常节点为7和3(分别对比7/4和6/3的时候);
然后进行最后一步替换这两个节点的值就可以。

感觉把一个很简单的问题说复杂了,直接看一下代码:

public class Solution {
    private TreeNode preNode, firstMisNode, secondMisNode;
    public void recoverTree(TreeNode root)
    {
        preNode = firstMisNode = secondMisNode = null;
        dfs(root);
        int tmp = firstMisNode.val;
        firstMisNode.val = secondMisNode.val;
        secondMisNode.val = tmp;
    }

    private void dfs(TreeNode root)
    {
        if (root == null)
        {
            return;
        }
        dfs(root.left);
        if (preNode != null && preNode.val > root.val)
        {
            if (firstMisNode == null)
                firstMisNode = preNode;
            secondMisNode = root;
        }
        preNode = root;    //这里可以看成是中序遍历当前节点的过程,只不过顺便标记一下成前一个节点preNode(相对下一个节点而言)
        dfs(root.right);
    }
}

再做一下扩展,判断一棵树是不是二叉搜索树。
和上面的思路大致是相同的,有两种实现的代码,都很直观简单,但代码简洁性,时间复杂度和空间复杂度第二种都要优于第一种。

代码实现一:

public class Solution
{
    public boolean isValidBST(TreeNode root)
    {
        pre=null;
        if(root==null)
            return true;
        ArrayList<Integer> aList=new ArrayList<Integer>();
        visitBST(root,aList);
        boolean res=true;
        for(int i=1;i<aList.size();i++){
            if(aList.get(i)<aList.get(i-1)){
                res=false;
                break;
            }
        }
        return res;
    }
    private void visitBST(TreeNode root,ArrayList<Integer> aList){
        if(root==null)
            return;
        visitBST(root.left,aList);
        aList.add(root.val);
        visitBST(root.right,aList);
    }
}

代码实现二,算是比较直观简洁了:

public class Solution {
    TreeNode pre=null;
    public boolean isValidBST(TreeNode root) {
        if(root==null)
            return true;
        if(!isValidBST(root.left))
            return false;
        if(pre!=null&&pre.val>=root.val)
                return false;
        pre=root;
        return isValidBST(root.right);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值