给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。
所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。
举例
提示:
树中节点数在范围 [1, 104] 内
0 <= Node.val <= 104
树中每个节点的值都是 唯一 的
题目数据保证输入是一棵有效的二叉搜索树
0 <= low <= high <= 104
解题思路:递归 或 迭代
方法一:递归(不难想到)
/**
* 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 null;
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
if(root.val < low) return root.right;
else if(root.val > high) return root.left;
else return root;
}
}
方法二:迭代 ⭐
(基本思路有点像中序遍历的普通迭代法)
① 首先找到满足条件的根节点
② 从该根节点开始,更新左子树(查看是否会超出下界)
一直向左孩子查找,直到找到不满足条件的node【node和node的左子树均不满足要求→需要继续判断node的右子树是否满足要求】,并且找的过程中记录下它的父节点parent,父节点的左孩子设置为node.right,并把当前node设置为node.right,继续重复上述过程【重新连接后要继续判断node是否满足】,直到node == null。
③ 从该根节点开始,更新右子树(查看是否会超出上界)
一直向右孩子查找,直到找到不满足条件的node【node和node的右子树均不满足要求→需要继续判断node的左子树是否满足要求】,并且找的过程中记录下它的父节点parent,父节点的右孩子设置为node.left,并把当前node设置为node.left,继续重复上述过程【重新连接后要继续判断node是否满足】,直到node == null。
/**
* 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) {
// 1. 更新root
while(root != null){
if(root.val < low) root = root.right;
else if(root.val > high) root = root.left;
else break;
}
if(root == null) return root;
// 此时root是有效的
// 2. 更新root的左子树,看是否有小于下界的
TreeNode cur = root;
while(cur != null){
while(cur.left != null && cur.left.val < low){
cur.left = cur.left.right; // 继续修建右子树
}
cur = cur.left;
}
// 3. 更新root的右子树,看是否有大于下界的
cur = root;
while(cur != null){
while(cur.right != null && cur.right.val > high){
cur.right = cur.right.left; // 继续修建右子树
}
cur = cur.right;
}
return root;
}
}