1 二叉搜索树修剪
https://leetcode.cn/problems/trim-a-binary-search-tree/description/
给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。
所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。
2 思路
修剪就是将不在要求范围内的节点都删除,属于多个节点的删除操作
对于二叉搜索树来说,如果当前节点不在范围内,其左右子树也可能不在范围内,此时删除节点就方便很多
比如:
保留的范围为 [num1, num2]
如果一个当前节点小于num1,此时直接将其和其左孩子都删除就可以,因为它们都小于num1;如果大于num2也是一样的;对于第一种情况,其右子树中可能有满足条件的节点,因此还需要对其右子树进行递归操作,这样左右子树都完成了处理。
代码:
class Solution{
public TreeNode trimBST(TreeNode root, int low, int high) {
if (root == null) return null;
if (root.val < low) {
// 如果在此处返回,则root.right 不会继续处理,其孩子节点可能有满足的情况
TreeNode right = trimBST(root.right, low, high);
return right;
// 此处不能返回root.right 因为root.right可能也需要处理,此时返回处理后的结果
}
if (root.val > high) {
TreeNode left = trimBST(root.left, low, high);
return left;
}
// 不满足情况,继续递归
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
}
【注意】处理满足条件的节点时不能直接返回结果,此时返回的节点以及其孩子不会被继续处理
2 完整代码
import java.util.*;
class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode() {}
public TreeNode(int val) { this.val = val;}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Solution solution = new Solution();
while (in.hasNext()) {
String[] strNums = in.nextLine().split(" ");
int low = Integer.parseInt(in.nextLine());
int high = Integer.parseInt(in.nextLine());
List<TreeNode> nodes = new LinkedList<>();
for (String strNum : strNums) {
if (!strNum.isEmpty()) {
if (strNum.equals("null")) {
nodes.add(null);
} else {
nodes.add(new TreeNode(Integer.parseInt(strNum)));
}
}
}
TreeNode root = constructTree(nodes);
TreeNode r = solution.trimBST(root, low, high);
preorderTree(r);
}
}
public static void preorderTree(TreeNode root) {
if (root != null) {
System.out.print(root.val + " ");
preorderTree(root.left);
preorderTree(root.right);
}
}
public static TreeNode constructTree(List<TreeNode> nodes) {
if (!nodes.isEmpty()) {
TreeNode node = nodes.remove(0);
if (node != null) {
node.left = constructTree(nodes);
node.right = constructTree(nodes);
}
return node;
}
return null;
}
}
/*
test case
3 0 null 2 1 null null null 4
1
3
*/