99. Recover Binary Search Tree

题目描述(困难难度)

在这里插入图片描述

二分查找树的题,一个合法的二分查找树随机交换了两个数的位置,然后让我们恢复二分查找树。不能改变原来的结构,只是改变两个数的位置。二分查找树定义如下:

若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
任意节点的左、右子树也分别为二叉查找树;
没有键值相等的节点。

解法一 递归

让我们来考虑交换的位置的可能:

  • 根节点和左子树的某个数字交换 -> 由于根节点大于左子树中的所有数,所以交换后我们只要找左子树中最大的那个数,就是所交换的那个数
  • 根节点和右子树的某个数字交换 -> 由于根节点小于右子树中的所有数,所以交换后我们只要在右子树中最小的那个数,就是所交换的那个数
  • 左子树和右子树的两个数字交换 -> 找左子树中最大的数,右子树中最小的数,即对应两个交换的数
  • 左子树中的两个数字交换
  • 右子树中的两个数字交换

思想有了,代码很好写了。

public void recoverTree2(TreeNode root) {
    if (root == null) {
        return;
    }
    //寻找左子树中最大的节点
    TreeNode maxLeft = getMaxOfBST(root.left);
    //寻找右子树中最小的节点
    TreeNode minRight = getMinOfBST(root.right);

    if (minRight != null && maxLeft != null) {
        //左边的大于根节点,右边的小于根节点,对应情况 3,左右子树中的两个数字交换
        if ( maxLeft.val > root.val && minRight.val < root.val) {
            int temp = minRight.val;
            minRight.val = maxLeft.val;
            maxLeft.val = temp;
        }
    }

    if (maxLeft != null) {
        //左边最大的大于根节点,对应情况 1,根节点和左子树的某个数做了交换
        if (maxLeft.val > root.val) {
            int temp = maxLeft.val;
            maxLeft.val = root.val;
            root.val = temp;
        }
    }

    if (minRight != null) {
        //右边最小的小于根节点,对应情况 2,根节点和右子树的某个数做了交换
        if (minRight.val < root.val) {
            int temp = minRight.val;
            minRight.val = root.val;
            root.val = temp;
        }
    }
    //对应情况 4,左子树中的两个数进行了交换
    recoverTree(root.left);
    //对应情况 5,右子树中的两个数进行了交换
    recoverTree(root.right);

}
//寻找树中最小的节点
private TreeNode getMinOfBST(TreeNode root) {
    if (root == null) {
        return null;
    }
    TreeNode minLeft = getMinOfBST(root.left);
    TreeNode minRight = getMinOfBST(root.right);
    TreeNode min = root;
    if (minLeft != null && min.val > minLeft.val) {
        min = minLeft;
    }
    if (minRight != null && min.val > minRight.val) {
        min = minRight;
    }
    return min;
}

//寻找树中最大的节点
private TreeNode getMaxOfBST(TreeNode root) {
    if (root == null) {
        return null;
    }
    TreeNode maxLeft = getMaxOfBST(root.left);
    TreeNode maxRight = getMaxOfBST(root.right);
    TreeNode max = root;
    if (maxLeft != null && max.val < maxLeft.val) {
        max = maxLeft;
    }
    if (maxRight != null && max.val < maxRight.val) {
        max = maxRight;
    }
    return max;
}

在这里插入图片描述

参考文献

1.https://zhuanlan.zhihu.com/p/73093380

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安替-AnTi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值