comments | difficulty | edit_url | tags | ||||
---|---|---|---|---|---|---|---|
true |
中等 |
|
给你二叉搜索树的根节点 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, 104]
内 0 <= Node.val <= 104
- 树中每个节点的值都是 唯一 的
- 题目数据保证输入是一棵有效的二叉搜索树
0 <= low <= high <= 104
判断 root.val
与 low
和 high
的大小关系:
- 若
root.val
大于high
,说明当前root
节点与其右子树所有节点的值均大于high
,那么递归修剪root.left
即可; - 若
root.val
小于low
,说明当前root
节点与其左子树所有节点的值均小于low
,那么递归修剪root.right
即可; - 若
root.val
在[low, high]
之间,说明当前root
应该保留,递归修剪root.left
,root.right
,并且返回root
。
递归的终止条件是 root
节点为空。
时间复杂度
# 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]:
def dfs(root):
if root is None:
return root
if root.val > high:
return dfs(root.left)
if root.val < low:
return dfs(root.right)
root.left = dfs(root.left)
root.right = dfs(root.right)
return root
return dfs(root)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if (root == null) {
return root;
}
if (root.val > high) {
return trimBST(root.left, low, high);
}
if (root.val < low) {
return trimBST(root.right, low, high);
}
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
}
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
if (!root) return root;
if (root->val > high) return trimBST(root->left, low, high);
if (root->val < low) return trimBST(root->right, low, high);
root->left = trimBST(root->left, low, high);
root->right = trimBST(root->right, low, high);
return root;
}
};
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func trimBST(root *TreeNode, low int, high int) *TreeNode {
if root == nil {
return root
}
if root.Val > high {
return trimBST(root.Left, low, high)
}
if root.Val < low {
return trimBST(root.Right, low, high)
}
root.Left = trimBST(root.Left, low, high)
root.Right = trimBST(root.Right, low, high)
return root
}
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
function trimBST(root: TreeNode | null, low: number, high: number): TreeNode | null {
const dfs = (root: TreeNode | null) => {
if (root == null) {
return root;
}
const { val, left, right } = root;
if (val < low || val > high) {
return dfs(left) || dfs(right);
}
root.left = dfs(left);
root.right = dfs(right);
return root;
};
return dfs(root);
}
// Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
// pub val: i32,
// pub left: Option<Rc<RefCell<TreeNode>>>,
// pub right: Option<Rc<RefCell<TreeNode>>>,
// }
//
// impl TreeNode {
// #[inline]
// pub fn new(val: i32) -> Self {
// TreeNode {
// val,
// left: None,
// right: None
// }
// }
// }
use std::cell::RefCell;
use std::rc::Rc;
impl Solution {
pub fn trim_bst(
mut root: Option<Rc<RefCell<TreeNode>>>,
low: i32,
high: i32,
) -> Option<Rc<RefCell<TreeNode>>> {
if root.is_none() {
return root;
}
{
let mut node = root.as_mut().unwrap().borrow_mut();
if node.val < low {
return Self::trim_bst(node.right.take(), low, high);
}
if node.val > high {
return Self::trim_bst(node.left.take(), low, high);
}
node.left = Self::trim_bst(node.left.take(), low, high);
node.right = Self::trim_bst(node.right.take(), low, high);
}
root
}
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} low
* @param {number} high
* @return {TreeNode}
*/
var trimBST = function (root, low, high) {
function dfs(root) {
if (!root) {
return root;
}
if (root.val < low) {
return dfs(root.right);
}
if (root.val > high) {
return dfs(root.left);
}
root.left = dfs(root.left);
root.right = dfs(root.right);
return root;
}
return dfs(root);
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* trimBST(struct TreeNode* root, int low, int high) {
if (!root) {
return root;
}
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;
}
我们先循环判断 root
,若 root.val
不在 [low, high]
之间,那么直接将 root
置为对应的左孩子或右孩子,循环直至 root
为空或者 root.val
在 [low, high]
之间。
若此时 root
为空,直接返回。否则,说明 root
是一个需要保留的节点。接下来只需要分别迭代修剪 root
的左右子树。
以左子树 node = root.left
为例:
- 若
node.left.val
小于low
,那么node.left
及其左孩子均不满足条件,我们直接将node.left
置为node.left.right
; - 否则,我们将
node
置为node.left
; - 循环判断,直至
node.left
为空。
右子树的修剪过程与之类似。
时间复杂度
# 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.left if root.val > high else root.right
if root is None:
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
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
while (root != null && (root.val < low || root.val > high)) {
root = root.val < low ? root.right : root.left;
}
if (root == null) {
return null;
}
TreeNode node = root;
while (node.left != null) {
if (node.left.val < low) {
node.left = node.left.right;
} else {
node = node.left;
}
}
node = root;
while (node.right != null) {
if (node.right.val > high) {
node.right = node.right.left;
} else {
node = node.right;
}
}
return root;
}
}
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* trimBST(TreeNode* root, int low, int high) {
while (root && (root->val < low || root->val > high)) {
root = root->val < low ? root->right : root->left;
}
if (!root) {
return root;
}
TreeNode* 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;
}
};
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func trimBST(root *TreeNode, low int, high int) *TreeNode {
for root != nil && (root.Val < low || root.Val > high) {
if root.Val < low {
root = root.Right
} else {
root = root.Left
}
}
if root == nil {
return nil
}
node := root
for node.Left != nil {
if node.Left.Val < low {
node.Left = node.Left.Right
} else {
node = node.Left
}
}
node = root
for node.Right != nil {
if node.Right.Val > high {
node.Right = node.Right.Left
} else {
node = node.Right
}
}
return root
}
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} low
* @param {number} high
* @return {TreeNode}
*/
var trimBST = function (root, low, high) {
while (root && (root.val < low || root.val > high)) {
root = root.val < low ? root.right : root.left;
}
if (!root) {
return root;
}
let 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;
};