Medium

题目描述

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

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

示例 1:

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

示例 2:

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

提示:

  • 树中节点数在范围 [1, 10^4]
  • 0 <= Node.val <= 10^4
  • 树中每个节点的值都是唯一的
  • 题目数据保证输入是一棵有效的二叉搜索树
  • 0 <= low <= high <= 10^4

解题思路

这道题利用二叉搜索树的性质来解决。对于BST,左子树的所有节点值都小于根节点,右子树的所有节点值都大于根节点。

核心思路:

  1. 如果当前节点值小于 low,说明当前节点和它的左子树都需要被修剪掉,返回修剪后的右子树
  2. 如果当前节点值大于 high,说明当前节点和它的右子树都需要被修剪掉,返回修剪后的左子树
  3. 如果当前节点值在 [low, high] 范围内,保留当前节点,递归修剪左右子树

算法步骤:

  • 递归处理每个节点
  • 根据节点值与边界的关系决定修剪策略
  • 对于保留的节点,继续递归处理其子树
  • 最终返回修剪后的树的根节点

这种方法充分利用了BST的有序性,能够高效地完成修剪操作,时间复杂度为O(n),空间复杂度为O(h),其中h是树的高度。

代码实现

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if (!root) return nullptr;
        
        if (root->val < low) {
            return trimBST(root->right, low, high);
        }
        
        if (root->val > high) {
            return trimBST(root->left, low, high);
        }
        
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);
        
        return root;
    }
};
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)
        
        if root.val > high:
            return self.trimBST(root.left, low, high)
        
        root.left = self.trimBST(root.left, low, high)
        root.right = self.trimBST(root.right, low, high)
        
        return root
public class Solution {
    public TreeNode TrimBST(TreeNode root, int low, int high) {
        if (root == null) return null;
        
        if (root.val < low) {
            return TrimBST(root.right, low, high);
        }
        
        if (root.val > high) {
            return TrimBST(root.left, low, high);
        }
        
        root.left = TrimBST(root.left, low, high);
        root.right = TrimBST(root.right, low, high);
        
        return root;
    }
}
var trimBST = function(root, low, high) {
    if (!root) return null;
    
    if (root.val < low) {
        return trimBST(root.right, low, high);
    }
    
    if (root.val > high) {
        return trimBST(root.left, low, high);
    }
    
    root.left = trimBST(root.left, low, high);
    root.right = trimBST(root.right, low, high);
    
    return root;
};

复杂度分析

复杂度分析
时间复杂度O(n),其中 n 是树中节点的数量,最坏情况下需要访问所有节点
空间复杂度O(h),其中 h 是树的高度,递归调用栈的深度