Leetcode 669. 修剪二叉搜索树

1.题目描述

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

Leetcode 669. 修剪二叉搜索树_第1张图片

输入:root = [1,0,2], low = 1, high = 2
输出:[1,null,2]
Leetcode 669. 修剪二叉搜索树_第2张图片

输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3
输出:[3,2,null,1]


提示:

  • 树中节点数在范围 [ 1 , 1 0 4 ] [1, 10^4] [1,104]
  • 0 < = N o d e . v a l < = 1 0 4 0 <= Node.val <= 10^4 0<=Node.val<=104
  • 树中每个节点的值都是 唯一 的
  • 题目数据保证输入是一棵有效的二叉搜索树
  • 0 < = l o w < = h i g h < = 1 0 4 0 <= low <= high <= 10^4 0<=low<=high<=104

2.思路分析

2.1 递归法

确定递归函数要处理的参数以及返回值

  • 使用原函数作为递归函数

确定终止条件

  • 如果结点为空结点,直接返回空结点;

确定单层搜索逻辑

  • 若 root.val 小于边界值 low,则 root 的左子树必然均小于边界值,我们递归处理 root.right 即可;
  • 若 root.val 大于边界值 high,则 root 的右子树必然均大于边界值,我们递归处理 root.left 即可;
  • 若 root.val 符合要求,则 root 可被保留,递归处理其左右节点并重新赋值即可。

2.2 迭代法

  • 起始先从给定的 root 进行出发,找到第一个满足值符合 [low, high] 范围的节点,该节点为最后要返回的根节点 ans
  • 考虑如何修剪 ans 的左右节点:当根节点符合 [low, high]要求时,修剪左右节点过程中仅需考虑一边的边界值即可。
  • 即对于 ans.left 只需考虑将值小于 low 的节点去掉(因为二叉搜索树的特性,ans 满足不大于 high 要求,则其左节点必然满足)
  • 同理 ans.right 只需要考虑将大于 high 的节点去掉即可。

3.代码实现

3.1 递归法

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
        # 终止条件
        if not root:
            return None
        # 单层搜索逻辑
        if root.val < low:
            return self.trimBST(root.right, low, high)
        elif root.val > high:
            return self.trimBST(root.left, low, high)
        else:
            root.left = self.trimBST(root.left, low, high)
            root.right = self.trimBST(root.right, low, high)
        return root
  • 时间复杂度:O(n)
  • 空间复杂度:忽略递归带来的额外空间开销,复杂度为 O(1)

3.2 迭代法

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
        # 寻找一个符合条件的区间
        while root and (root.val < low or root.val > high):
            root = root.right if root.val < low else root.left
        if not root:
            return None
        node = root
        while node.left:
            if node.left.val < low:
                node.left = node.left.right
            else:
                node = node.left
        node = root
        while node.right:
            if node.right.val > high:
                node.right = node.right.left
            else:
                node = node.right
        return root
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

你可能感兴趣的:(数据结构,Leetcode,leetcode,算法,职场和发展)