修剪二叉搜索树

力扣题目链接(opens new window)

给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。


思路

题目描述得有点唬人,其实意思就是给一个区间范围(比如[2, 7]),然后要求你把节点值不在这个范围内的节点给删除掉,并且之后还是二叉搜索树

一种经典的错误思路是:遇到不符合区间的节点时,直接返回NULL给上一个节点

这样做的话,如果不满足条件的节点的子树还有满足条件的值的话,也会被舍弃,从而出错

当我们找到一个不在规定范围内的节点时,首先要判断它是小于范围还是大于范围

如果节点(假设为A)的值小于规定范围,根据二叉搜索树的性质,其右子树有可能还存在满足规定范围的节点,因此需要继续遍历其右子树

如果节点(假设为A)的值大于规定范围,根据二叉搜索树的性质,其左子树有可能还存在满足规定范围的节点,因此需要继续遍历其左子树

基本思路是这样的

下面来看代码

代码

还是使用递归法来做

1、确定递归函数的参数和返回值

参数肯定是根节点啦,因为我们需要修改二叉树,所以修改的新值需要层层传递到上层递归的调用处,因此需要返回值

那么可以直接用解题模板

class Solution {
public:
//确定递归函数的参数和返回值
TreeNode* trimBST(TreeNode* root, int low, int high) { }
};

2、确定终止条件

如果当前输入的节点为空,那么应该返回空并结束递归

class Solution {
public:
//确定递归函数的参数和返回值
TreeNode* trimBST(TreeNode* root, int low, int high) {
//确定终止条件
if(root == NULL) return NULL;
}
};

3、确定单层处理逻辑

当前节点小于规定范围时,遍历其右子树

class Solution {
public:
//确定递归函数的参数和返回值
TreeNode* trimBST(TreeNode* root, int low, int high) {
//确定终止条件
if(root == NULL) return NULL; //确定单层递归逻辑
if(root->val < low){//遍历其右子树
TreeNode* right = trimBST(root->right, low, high);
return right;
}
}
};

解释一下递归右子树的代码的含义

上面那样写的意思是:使用当前节点作为根节点,递归遍历其右子树,最后返回一颗经过修剪的满足条件的右子树

实在不理解或者忘了,可以自己模拟一下过程

同理,当前节点大于规定范围时,遍历其左子树

class Solution {
public:
//确定递归函数的参数和返回值
TreeNode* trimBST(TreeNode* root, int low, int high) {
//确定终止条件
if(root == NULL) return NULL; //确定单层递归逻辑
if(root->val < low){//遍历其右子树
TreeNode* right = trimBST(root->right, low, high);
return 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; }
};

注意,这里我们要搜索的是当前节点的左子树或右子树(是整颗树)

还是模拟一下过程把怕之后看又不记得了

首先我们将根节点输入到递归函数中,此时其不满足递归结束的条件,假设其值也在规定范围内

那么此时会调用递归,去遍历根节点的左右子树【第一层递归,希望返回的是一颗修剪后的左或右子树

然后进入左子树,若当前左子树的根节点不在规定范围内,则触发对应的单层处理逻辑

假设此时触发的是root->val < low条件,那么回去递归遍历当前左子树根节点的右子树【第二层递归,希望返回的是一颗修剪后的右子树

假设其右子树均满足规定范围,那么当递归遍历到叶子节点后,会触发终止条件,然后每层递归都往上返回自己的结果,从而得到修改后的树

【LeetCode二叉树#18】修剪二叉搜索树(涉及重构二叉树与递归回溯)的更多相关文章

  1. 代码随想录算法训练营day23 | leetcode 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树

    LeetCode 669. 修剪二叉搜索树 分析1.0 递归遍历树时删除符合条件(不在区间中)的节点-如何遍历如何删除 如果当前节点大于范围,递归左树,反之右树 当前节点不在范围内,删除它,把它的子树 ...

  2. LeetCode 669. 修剪二叉搜索树(Trim a Binary Search Tree)

    669. 修剪二叉搜索树 669. Trim a Binary Search Tree 题目描述 LeetCode LeetCode669. Trim a Binary Search Tree简单 J ...

  3. LeetCode 669. Trim a Binary Search Tree修剪二叉搜索树 (C++)

    题目: Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so th ...

  4. Java实现 LeetCode 669 修剪二叉搜索树(遍历树)

    669. 修剪二叉搜索树 给定一个二叉搜索树,同时给定最小边界L 和最大边界 R.通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) .你可能需要改变树的根节点,所以结果应当返回 ...

  5. [Swift]LeetCode669. 修剪二叉搜索树 | Trim a Binary Search Tree

    Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so that a ...

  6. 【JavaScript】Leetcode每日一题-二叉搜索树的范围和

    [JavaScript]Leetcode每日一题-二叉搜索树的范围和 [题目描述] 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和. 示例1: 输入: ...

  7. 【python】Leetcode每日一题-二叉搜索树节点最小距离

    [python]Leetcode每日一题-二叉搜索树节点最小距离 [题目描述] 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 . 示例1: 输入:root = [4 ...

  8. 【LeetCode】98. 验证二叉搜索树

    98. 验证二叉搜索树 知识点:二叉树:递归 题目描述 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大 ...

  9. LeetCode 96——不同的二叉搜索树

    1. 题目 2. 解答 以 \(1, 2, \cdots, n\) 构建二叉搜索树,其中,任意数字都可以作为根节点来构建二叉搜索树.当我们将某一个数字作为根节点后,其左边数据将构建为左子树,右边数据将 ...

  10. LeetCode.938-范围内求二叉搜索树节点值之和(Range Sum of BST)

    这是悦乐书的第359次更新,第386篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第221题(顺位题号是938).给定二叉搜索树的根节点,返回节点值在[L,R]之间的所有 ...

随机推荐

  1. [转帖]OceanBase 在线与离线安装方式详解

    各位好,今天给大家带来一篇有关 OceanBase 在线与离线安装方式的解读.首先我们来讨论一下一日常工作中的一些场景,大家经常会遇到以下几种情况: 公司网络条件很不错,在线下载速度很快,安装软件直接 ...

  2. [转帖]使用Linux命令快速查看某一行

      原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 当年,我还是Linux菜鸟的时候,就在简历上写着精通Linux命令了,而当面试官问我"如何快速查看 ...

  3. [转帖]CPU的制造和概念

    https://plantegg.github.io/2021/06/01/CPU%E7%9A%84%E5%88%B6%E9%80%A0%E5%92%8C%E6%A6%82%E5%BF%B5/ 为了让 ...

  4. Mysql数据库查看Database的大小的方法

    最简单的方法为: select concat(round(sum(data_length/1024/1024),2),'MB') as data from INFORMATION_SCHEMA.tab ...

  5. ESXi查看底层存储磁盘厂商型号的方式与方法

    ESXi查看底层存储磁盘厂商型号的方式与方法 背景 公司一台过保的服务器出现了磁盘告警 Vendor不太靠谱. 过保的机器就不管了 不买他们的服务器也不说一下是啥硬盘. 想自己替换,需要先获取磁盘的型 ...

  6. git查看自己是从那个分支建的分支

    可能发生的情况 很多时候,开始建分支的时候, 能够确认自己是那个分支建的,但是当写完功能之后, 再去回想,有时是忘记自己基于那个分支建的分支. 这时有一个命令的话就可以很快的定位了. 查看创建的分支来 ...

  7. ABP vNext系列文章04---DynamicClient动态代理

    一.动态代理在ABP系统中的应用 1.它主要在做什么事件 之前开发系统想要在后台调用别的服务都是用HttpClient发起请求,在abp vnext中不需要我们这样做了, 你只要知道服务调用的接口方法 ...

  8. 🛠 开源即时通讯(IM)项目OpenIM源码部署指南

    OpenIM的部署涉及多个组件,并支持多种方式,包括源码.Docker和Kubernetes等.这要求在确保不同部署方式之间的兼容性同时,还需有效管理各版本之间的差异.确实,这些都是复杂的问题,涉及到 ...

  9. k8s 中的网络

    k8s 中的网络模型 CNI 网络插件 CNI 的设计思想 k8s 中的三层网络 Flannel 的 host-gw Calico 参考 k8s 中的网络模型 CNI 网络插件 docker 容器的网 ...

  10. 7.0 Python 面向对象编程

    python是一种面向对象的编程语言,面向对象编程(Object-Oriented Programming,OOP)是一种编程思想,其核心概念是"对象".对象是指一个具有特定属性和 ...