返回

二叉搜索树修剪

前端

LeetCode 刷题日记 NO.48:修剪二叉搜索树

正文

引言

大家好,欢迎来到我的一周一次的 LeetCode 刷题日记!今天,我将带领大家解决一道经典的 LeetCode 难题——第 669 题:修剪二叉搜索树

这道题考验的是我们的二叉搜索树操作能力,需要我们根据给定的最小值和最大值,对二叉搜索树进行适当的修剪,形成新的二叉搜索树,且满足给定的条件。

题目

给你二叉搜索树的根节点 root,同时给定最小边界 low 和最大边界 high。通过修剪二叉搜索树,使得所修剪后的二叉搜索树满足:

  • 每个节点的值都在 [low, high] 之内
  • 二叉搜索树的性质仍然保持(即:每个子树的左子树节点值小于其父节点值,右子树节点值大于其父节点值)

修剪后的二叉搜索树可能是原来二叉搜索树的一部分,或为空。

解题思路

第一步:二分法快速定位

修剪操作本质上是将不满足条件的子树从二叉搜索树中删除。由于二叉搜索树的特性,我们可以利用二分法快速定位不满足条件的子树。

具体而言,我们可以从根节点出发,判断其值是否在 [low, high] 范围内。如果不在,则说明该子树不满足条件,直接将其删除。否则,继续分别判断左子树和右子树是否满足条件。

第二步:修剪子树

对于不满足条件的子树,我们可以直接将其删除,并将其子树连接到父节点的合适位置(取决于子树的值是小于还是大于父节点)。

第三步:递归执行

完成上述操作后,对满足条件的子树(即父节点),递归执行以上步骤,直到遍历完整个二叉搜索树。

代码实现

def trimBST(root, low, high):
    if not root:
        return None

    if root.val < low:
        return trimBST(root.right, low, high)
    elif root.val > high:
        return trimBST(root.left, low, high)
    else:
        root.left = trimBST(root.left, low, high)
        root.right = trimBST(root.right, low, high)
        return root

复杂度分析

  • 时间复杂度:O(n),其中 n 为二叉搜索树的节点数。由于我们是递归遍历二叉搜索树,因此时间复杂度与二叉搜索树的大小成正比。
  • 空间复杂度:O(n),递归过程中需要额外的空间存储函数调用栈。

总结

LeetCode 第 669 题是一道经典的二叉搜索树操作题,通过二分法和递归修剪,我们可以高效地将二叉搜索树修剪为满足给定条件的新二叉搜索树。希望今天的分享对大家有帮助!

往期回顾

LeetCode 刷题日记 NO.47:最长回文子串
LeetCode 刷题日记 NO.46:合并两个有序数组
更多文章

交流讨论

欢迎大家在评论区留言交流,分享你们对这道题的理解和解决方法。同时,也欢迎大家提出新的题目,让我们一起刷题,共同进步!

附录