( “树” 之 BST) 669. 修剪二叉搜索树 ——【Leetcode每日一题】

news2024/11/17 11:41:42

二叉查找树(BST):根节点大于等于左子树所有节点,小于等于右子树所有节点。
二叉查找树中序遍历有序。

669. 修剪二叉搜索树

给你二叉搜索树的根节点 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 , 1 0 4 ] [1, 10^4] [1,104]
  • 0 < = N o d e . v a l < = 1 0 4 0 <= Node.val <= 10^4 0<=Node.val<=104
  • 树中每个节点的值都是 唯一 的
  • 题目数据保证输入是一棵有效的二叉搜索树
  • 0 < = l o w < = h i g h < = 1 0 4 0 <= low <= high <= 10^4 0<=low<=high<=104

思路:

法一:递归:

任意一个节点的val,对给定的范围只有三种可能,等于小于大于

  1. 等于:也就在给定的范围内,则保留,再分别判断该节点的左子树和右子树;
  2. 小于:当该节点小于给定范围的最小值时,要将该节点以及该节点的左子树都修剪掉,让该节点的父节点的左指针指向该节点的右子树,再进行判断;
  3. 大于:当该节点大于给定范围的最大值时,要将该节点以及该节点的右子树都修剪掉,让该节点的父节点的右指针指向该节点的左子树,再进行判断;

法二:迭代:

该题自然能够使用「迭代」进行求解:起始先从给定的 root 进行出发,找到第一个满足值符合 [low,high]范围的节点,该节点为最后要返回的真正的根节点 root

然后分别处理root节点的左子树和右子树:

  • 这里对左子树,只需修剪掉小于所给范围的节点;
    • 若节点大于给定范围的最小值时,这该节点的右子树一定在范围内,不修剪,继续判断其左子树;
    • 若节点小于给定范围的最小值时,要将该节点以及该节点的左子树都修剪掉,让该节点的父节点的左指针指向该节点的右子树,再进行判断。
  • 而对右子树只需修剪掉大于所给范围的节点;
    • 若节点小于给定范围的最大值时,这该节点的左子树一定在范围内,不修剪,继续判断其左子树;
    • 若节点大于给定范围的最大值时,要将该节点以及该节点的右子树都修剪掉,让该节点的父节点的右指针指向该节点的左子树,再进行判断。

代码:(Java、C++)

法一:递归:
Java

/**
 * 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;
        if(root.val >= low && root.val <= high){
            root.left = trimBST(root.left, low, high);
            root.right = trimBST(root.right, low, high);
        }else if(root.val < low){
            return trimBST(root.right, low, high);
        }else if(root.val > high){
            return trimBST(root.left, low, high);
        }
        return root;
    }
}

C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if(root == nullptr) return nullptr;
        if(root->val >= low && root->val <= high){
            root->left = trimBST(root->left, low, high);
            root->right = trimBST(root->right, low, high);
        }else if(root->val < low){
            return trimBST(root->right, low, high);
        }else if(root->val > high){
            return trimBST(root->left, low, high);
        }
        return root;
    }
};

法二:迭代:
Java

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
       while(root != null && (root.val < low || root.val > high)){
           root = root.val < low ? root.right : root.left;
       }
       if(root == null) return null;
       TreeNode tem = root;
       while(tem.left != null){
           if(tem.left.val >= low){
               tem = tem.left;
           }else{
               tem.left = tem.left.right;
           }
       }
       tem = root;
       while(tem.right != null){
           if(tem.right.val <= high){
               tem = tem.right;
           }else{
               tem.right = tem.right.left;
           }
       }
       return root;
    }
}

C++

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        while(root != nullptr && (root->val < low || root->val > high)){
           root = root->val < low ? root->right : root->left;
       }
       if(root == nullptr) return nullptr;
       TreeNode* tem = root;
       while(tem->left != nullptr){
           if(tem->left->val >= low){
               tem = tem->left;
           }else{
               tem->left = tem->left->right;
           }
       }
       tem = root;
       while(tem->right != nullptr){
           if(tem->right->val <= high){
               tem = tem->right;
           }else{
               tem->right = tem->right->left;
           }
       }
       return root;
    }
};

运行结果:

在这里插入图片描述

复杂度分析:

  • 时间复杂度 O ( n ) O(n) O(n),其中 n 为二叉树的结点数目。
  • 空间复杂度 O ( 1 ) O(1) O(1)。迭代只需要常数级空间;而递归的话,递归栈最坏情况下需要 O ( n ) O(n) O(n) 的空间。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我 leetCode专栏,每日更新!

注: 如有不足,欢迎指正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/438473.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习——核函数

问&#xff1a;已知三维空间中的两个样本点分别为&#xff08;2&#xff0c;4&#xff0c;5)和(1&#xff0c;2&#xff0c;3)&#xff0c;定义核函数表达式为:试计算这两个样本点映射到十维空间后的 答&#xff1a;首先计算两个样本点的平方内积2*14*25*325 然后代入核函数表…

互联网医院软件|互联网医院系统开发|在线问诊提高医疗效率

互联网医院系统源码开发设计理念是以患者为中心&#xff0c;将医院的各个科室、医生资源进行有效的整合和调配。互联网医院系统开发是基于最新的Web技术和云计算技术所构建的一种全新的医疗信息化平台&#xff0c;可以通过网页、小程序等多种方式&#xff0c;为患者提供在线预约…

Logstash:通过 lookups 来丰富数据

如果你想了解更多关于 lookup 的内容&#xff0c;请参阅文章 “Elastic&#xff1a;开发者上手指南” 中的 “丰富数据及 lookup” 章节。在今天的文章中&#xff0c;我来总结在 Logstash 中一些常用的 lookups。如下的这些插件可以帮助你使用附加信息丰富数据&#xff0c;例如…

基于深度学习的车型识别系统(Python+清新界面+数据集)

摘要&#xff1a;基于深度学习的车型识别系统用于识别不同类型的车辆&#xff0c;应用YOLO V5算法根据不同尺寸大小区分和检测车辆&#xff0c;并统计各类型数量以辅助智能交通管理。本文详细介绍车型识别系统&#xff0c;在介绍算法原理的同时&#xff0c;给出Python的实现代码…

浏览器强缓存与协商缓存

一、强缓存 强制缓存的思想是&#xff0c;在浏览器内置数据库中缓存每次请求中 “可以被缓存” &#xff08;受到一些关键字的管控&#xff09;的静态资源如 image, css, js 文件&#xff0c; 当第二次请求被缓存过的资源时候&#xff0c;会通过校验两个字段 Expires 和 Cache-…

AAAI 2023MOVEDepth:基于单目线索和速度指导的自监督多帧深度估计

文章目录 解决的问题实施细节总结 会议/期刊&#xff1a;2023 AAAI 论文题目&#xff1a;《Crafting Monocular Cues and Velocity Guidance for Self-Supervised Multi-Frame Depth Learning》 论文链接&#xff1a;[JeffWang987/MOVEDepth: AAAI 2023]Crafting Monocular Cue…

Flutter TextField 交互实例 —— 新手礼包

大家好&#xff0c;我是 17。 新手礼包一共 3 篇文章&#xff0c;每篇都是描述尽量详细&#xff0c;实例讲解&#xff0c;包会&#xff01; Flutter Row 实例 —— 新手礼包Flutter TextField UI 实例 —— 新手礼包Flutter TextField 交互实例 —— 新手礼包 本篇包含所有常…

Unity打包WebGL: 导入Vue

Unity打包WebGL: 导入Vue 1. 介绍 1.1 任务 记录将Unity项目打包成WebGL&#xff0c;并集成到Vue项目中的过程。 1.2 环境 Unity:2021.3Vue: 2 2. Unity项目 2.1 UI界面 2.2 添加插件 构建WebGL项目需要添加一个.jslib文件&#xff0c;用于Unity脚本函数与JavaScript函数…

【FocalNet】学习笔记

1. 介绍 “FocalNet是map-based还是token-based模型呢&#xff1f;” FocalNet是token-based模型&#xff0c;与常见的【基于 feature map 的CNN】不同&#xff1b; 2. 模型代码 2.1 环境配置 [DINO | FocalNet-DINO] 2.1.1 配置CUDA11.1 Summary Driver: Not Selected…

FreeRTOS 时间管理

文章目录 一、FreeRTOS 延时函数1. 函数 vTaskDelay()2. 函数 prvAddCurrentTaskToDelayedList()3. 函数 vTaskDelayUntil() 二、FreeRTOS 系统时钟节拍 一、FreeRTOS 延时函数 1. 函数 vTaskDelay() 在 FreeRTOS 中延时函数也有相对模式和绝对模式&#xff0c;不过在 FreeRT…

epoll进阶

epoll除了提供select/poll那种IO事件的电平触发&#xff08;Level Triggered&#xff09;外&#xff0c;还提供了边沿触发&#xff08;Edge Triggered&#xff09;&#xff0c;这就使得用户空间程序有可能缓存IO状态&#xff0c;减少epoll_wait/epoll_pwait的调用&#xff0c;提…

经典文献阅读之--Orbeez-SLAM(单目稠密点云建图)

0. 简介 对于现在的VSLAM而言&#xff0c;现在越来越多的工作开始聚焦于如何将深度学习结合到VSLAM当中&#xff0c;而最近的这个工作就给出了一个比较合适的方法。《Orbeez-SLAM: A Real-time Monocular Visual SLAM with ORB Features and NeRF-realized Mapping》这篇文章&…

如何将模块加载到linux内核

一 顺利的情况 假设存在一个文件叫mymq.c,下该文件相同目录下的makefile如下语句&#xff1a; obj-y mymq.o 然后编译&#xff1a;编译完成了以后&#xff0c;mymq.c文件中&#xff0c;有个函数叫mymq_open,搜索这个函数在不在System.map文件中&#xff0c;如果在&#xff…

大屏使用echart开发省市地图数据,并点击省获取市地图数据

1. 本文在基础上进行改进&#xff0c;后端使用若依后端 IofTV-Screen: &#x1f525;一个基于 vue、datav、Echart 框架的物联网可视化&#xff08;大屏展示&#xff09;模板&#xff0c;提供数据动态刷新渲染、屏幕适应、数据滚动配置&#xff0c;内部图表自由替换、Mixins注入…

CDN与网络安全

DDoS攻击的影响远不止眼前所见。这些攻击不仅会造成巨大的经济损失&#xff0c;还会对受害公司或组织的声誉和形象产生严重影响。研究表明&#xff0c;受害公司至少需要10个小时才能开始解决攻击&#xff0c;而解除还需要4.5个小时。甚至在检测到攻击之前平均数小时&#xff0c…

一文详解Spring事务传播机制

背景 我们在使用Spring管理数据库事务的时候很方便&#xff0c;只需要在代理对象中引入注解Transactional 就可以开启事务了。在使用Transactional时&#xff0c;一般主要关心两个方面&#xff0c;一个是异常回滚的定义&#xff08;设置rollbackFor&#xff09;&#xff0c;另…

Python统计学:如何理解单样本t检验?

单样本的t检验 指样本的均值是否某个值存在差异。 比如一包薯片标的克重为50g&#xff0c;但每包不一定都是50g&#xff0c;那么我们可以对薯片进行随机抽样&#xff0c;检验它与50g是否有差异。 1 提出假设&#xff1a; 原假设&#xff1a;薯片的平均重量是50g&#xff1b; …

模板方法设计模式解读

目录 豆浆制作问题 模板方法模式基本介绍 基本介绍 模板方法模式的原理类图 模板方法模式解决豆浆制作问题 应用实例要求 思路分析和图解(类图) 模板方法模式的钩子方法 模板方法模式的注意事项和细节 豆浆制作问题 编写制作豆浆的程序&#xff0c;说明如下: 1) 制作豆…

Adobe认证是什么?

Adobe认证又称为Adobe国际认证(英文:Adobe Certified Professional)是Adobe公司CEO签发的权威国际认证体系&#xff0c;旨在为用户提供Adobe软件的专业认证。 Adobe认证包括产品技能认证和职业技能认证多个级别&#xff0c;从初学者到专业人士都可以参加。 Adobe认证覆盖了各…

ORA-27090故障,关于AIO-MAX-NR

在给某银行进行巡检时发现asm中的alert一直报ORA-27090错误。 通过巡检脚本&#xff0c;整理错误发生时间如下&#xff1a; 信息收集&#xff1a; 发生类似的错误&#xff0c;先收集alert日志的信息&#xff0c;操心系统的message日志。 Errors in file /u01/app/grid/diag/…