一、题目描述

给你二叉搜索树的根节点 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

二、题目解析

三、参考代码

1、Java 代码

// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 修剪二叉搜索树( LeetCode 669 ):https://leetcode-cn.com/problems/trim-a-binary-search-tree
class Solution {
     public TreeNode trimBST(TreeNode root, int low, int high) {

        // 边界情况处理
        if (root == null) {
            return null;
        }

        // 二叉搜索树的特点是,对于每一个节点 root 来说
        // root.left < root < root.right

        // 如果当前节点 root 的值小于了区间的最小值 low
        // 也就意味着它的左子树所有的节点都小于 low
        // 可以直接删除掉
        if (root.val < low) {

            // 删除操作就是把当前节点 root 的右子树移上来,替代 root 的位置
            root = root.right;

            // 接下来,继续修剪 root
            root = trimBST(root, low, high);

        // 如果当前节点 root 的值大于了区间的最大值 high
        // 也就意味着它的右子树所有的节点都大于 high
        // 可以直接删除掉
        } else if (root.val > high) {

            // 删除操作就是把当前节点 root 的左子树移上来,替代 root 的位置
            root = root.left;

            // 接下来,继续修剪 root
            root = trimBST(root, low, high);

        // 否则,说明 root 的值介于 [ low , high] 这个区间里面,是符合要求的
        // 需要去修剪它的左右子树
        } else {

            // 修剪 root.left
            root.left = trimBST(root.left, low, high);

            // 修剪 root.right
            root.right = trimBST(root.right, low, high);
        }

        // 返回修剪结果
        return root;
    }

}

2、C++ 代码

// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
// 代码有看不懂的地方一定要私聊咨询吴师兄呀
// 修剪二叉搜索树( LeetCode 669 ):https://leetcode-cn.com/problems/trim-a-binary-search-tree
class Solution
{
public:
    TreeNode *trimBST(TreeNode *root, int low, int high)
    {

        // 边界情况处理
        if (root == NULL)
        {
            return NULL;
        }

        // 二叉搜索树的特点是,对于每一个节点 root 来说
        // root->left < root < root->right

        // 如果当前节点 root 的值小于了区间的最小值 low
        // 也就意味着它的左子树所有的节点都小于 low
        // 可以直接删除掉
        if (root->val < low)
        {

            // 删除操作就是把当前节点 root 的右子树移上来,替代 root 的位置
            root = root->right;

            // 接下来,继续修剪 root
            root = trimBST(root, low, high);

            // 如果当前节点 root 的值大于了区间的最大值 high
            // 也就意味着它的右子树所有的节点都大于 high
            // 可以直接删除掉
        }
        else if (root->val > high)
        {

            // 删除操作就是把当前节点 root 的左子树移上来,替代 root 的位置
            root = root->left;

            // 接下来,继续修剪 root
            root = trimBST(root, low, high);

            // 否则,说明 root 的值介于 [ low , high] 这个区间里面,是符合要求的
            // 需要去修剪它的左右子树
        }
        else
        {

            // 修剪 root->left
            root->left = trimBST(root->left, low, high);

            // 修剪 root->right
            root->right = trimBST(root->right, low, high);
        }

        // 返回修剪结果
        return root;
    }
};

3、Python 代码

# 登录 AlgoMooc 官网获取更多算法图解
# https://www.algomooc.com
# 作者:程序员吴师兄
# 代码有看不懂的地方一定要私聊咨询吴师兄呀
# 修剪二叉搜索树( LeetCode 669 ):https://leetcode-cn.com/problems/trim-a-binary-search-tree
class Solution:
    def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:

        # 边界情况处理
        if not root :
            return None 

        # 二叉搜索树的特点是,对于每一个节点 root 来说
        # root.left < root < root.right

        # 如果当前节点 root 的值小于了区间的最小值 low
        # 也就意味着它的左子树所有的节点都小于 low
        # 可以直接删除掉
        if root.val < low :

            # 删除操作就是把当前节点 root 的右子树移上来,替代 root 的位置
            root = root.right 

            # 接下来,继续修剪 root
            root = self.trimBST(root, low, high) 

        # 如果当前节点 root 的值大于了区间的最大值 high
        # 也就意味着它的右子树所有的节点都大于 high
        # 可以直接删除掉
        elif root.val > high:

            # 删除操作就是把当前节点 root 的左子树移上来,替代 root 的位置
            root = root.left 

            # 接下来,继续修剪 root
            root = self.trimBST(root, low, high) 

        # 否则,说明 root 的值介于 [ low , high] 这个区间里面,是符合要求的
        # 需要去修剪它的左右子树
        else :

            # 修剪 root.left
            root.left = self.trimBST(root.left, low, high) 

            # 修剪 root.right
            root.right = self.trimBST(root.right, low, high) 


        # 返回修剪结果
        return root 

四、动画理解(没有声音)