【二叉树】LC669 - 中 - 二叉搜索树修剪

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
 */

参考

https://programmercarl.com/0669.修剪二叉搜索树.html#算法公开课

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值