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,左子树的所有节点值都小于根节点,右子树的所有节点值都大于根节点。
核心思路:
- 如果当前节点值小于
low,说明当前节点和它的左子树都需要被修剪掉,返回修剪后的右子树 - 如果当前节点值大于
high,说明当前节点和它的右子树都需要被修剪掉,返回修剪后的左子树 - 如果当前节点值在
[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 是树的高度,递归调用栈的深度 |