LeetCode669. 修剪二叉搜索树

news2024/12/25 23:46:55

669. 修剪二叉搜索树

文章目录

      • [669. 修剪二叉搜索树](https://leetcode.cn/problems/trim-a-binary-search-tree/)
        • 一、题目
        • 二、题解
          • 方法一:递归法
          • 方法二:迭代法


一、题目

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

示例 1:

img

输入:root = [1,0,2], low = 1, high = 2
输出:[1,null,2]

示例 2:

img

输入: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

二、题解

方法一:递归法

我们从根节点开始,逐个遍历树的节点,判断每个节点的值是否在给定的范围内。如果节点的值小于最小值(low),那么我们就需要修剪掉左子树,因为左子树的节点值都会更小,不可能在范围内。类似地,如果节点的值大于最大值(high),就需要修剪掉右子树。如果节点的值在范围内,我们保留这个节点,并分别递归修剪左子树和右子树。

下面是具体的算法思路以及解题步骤:

算法思路

  1. 如果树为空(即根节点为nullptr),直接返回nullptr,因为没有需要修剪的节点。
  2. 如果根节点的值小于最小值low,那么根节点以及左子树的所有节点都会小于low,所以我们需要修剪掉左子树,递归调用trimBST(root->right, low, high),返回修剪后的右子树作为新的根节点。
  3. 如果根节点的值大于最大值high,那么根节点以及右子树的所有节点都会大于high,所以我们需要修剪掉右子树,递归调用trimBST(root->left, low, high),返回修剪后的左子树作为新的根节点。
  4. 如果根节点的值在范围内,我们保留这个节点,并分别递归修剪左子树和右子树,即root->left = trimBST(root->left, low, high);root->right = trimBST(root->right, low, high);
  5. 最后返回修剪后的根节点。

具体实现

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if(root == nullptr) return nullptr;
        
        if(root->val < low){
            return trimBST(root->right, low, high);
        }
        if(root->val > high){
            return trimBST(root->left, low, high);
        }
        
        root->left = trimBST(root->left, low, high);
        root->right = trimBST(root->right, low, high);
        return root;
    }
};

算法分析

  • 时间复杂度:每个节点都被访问了一次,所以时间复杂度为O(N),其中N是树中的节点数。
  • 空间复杂度:递归调用的栈空间,最坏情况下(树完全不平衡),递归的深度可以达到N,所以空间复杂度为O(N)。
方法二:迭代法

算法思路

  1. 首先,处理根节点为空的情况。如果根节点为空,直接返回 nullptr,因为没有需要修剪的节点。
  2. 然后,我们需要找到新的根节点,它的值应当在范围 [low, high] 内。通过迭代循环,将当前根节点移动到满足条件的位置。如果当前根节点的值小于 low,说明应当修剪掉左子树,所以移动到右子树;如果当前根节点的值大于 high,说明应当修剪掉右子树,所以移动到左子树。
  3. 修剪左子树:从当前根节点开始,遍历到左子树的叶节点(最小值),如果叶节点的值小于 low,则将叶节点的右子树连接到当前叶节点的父节点上,从而删除小于 low 的节点。
  4. 修剪右子树:从当前根节点开始,遍历到右子树的叶节点(最大值),如果叶节点的值大于 high,则将叶节点的左子树连接到当前叶节点的父节点上,从而删除大于 high 的节点。
  5. 最后,返回修剪后的根节点。

具体实现

class Solution {
public:
    TreeNode* trimBST(TreeNode* root, int low, int high) {
        if (!root) return nullptr;  // 处理根节点为空的情况

        // 找到新的根节点,值在 [low, high] 范围内
        while (root && (root->val < low || root->val > high)) {
            if (root->val < low)
                root = root->right;
            else
                root = root->left;
        }
        
        TreeNode *cur = root;

        // 修剪左子树
        while (cur && cur->left) {
            if (cur->left->val < low) {
                cur->left = cur->left->right;
            } else {
                cur = cur->left;
            }
        }

        cur = root;

        // 修剪右子树
        while (cur && cur->right) {
            if (cur->right->val > high) {
                cur->right = cur->right->left;
            } else {
                cur = cur->right;
            }
        }

        return root;
    }
};

算法分析

  • 时间复杂度:这个解法的时间复杂度取决于两个遍历操作。第一个遍历操作在找到新的根节点时,最多访问树中所有节点,所以是 O(N)。第二个和第三个遍历操作在修剪左右子树时,最多访问树中所有节点,也是 O(N)。综合起来,总的时间复杂度是 O(N)。
  • 空间复杂度:这个解法没有使用额外的数据结构来存储中间结果,只使用了几个辅助变量,所以空间复杂度是 O(1)。

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

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

相关文章

【并发编程的艺术读书笔记】synchronized锁升级机制详解

锁升级机制 简介锁升级流程三种锁的优缺点 简介 synchronized在早期被称为重量级锁&#xff0c;而到现在已经得到不少优化。偏向锁、轻量级锁、重量级锁指的是synchronized三种形态。 锁升级流程 无锁&#xff08;Unlocked&#xff09;&#xff1a; 初始状态&#xff0c;表示…

​ 模拟嵌入式边缘计算卡设计方案:367-XC7Z100 板卡 基于zynq XC7Z100 FMC接口通用计算平台

基于zynq XC7Z100 FMC接口通用计算平台 一、板卡概述 北京太速科技板卡由SoC XC7Z100-2FFG900I芯片来完成卡主控及数字信号处理&#xff0c;XC7Z100内部集成了两个ARM Cortex-A9核和一个kintex 7的FPGA&#xff0c;通过PL端FPGA扩展FMC、光纤、IO等接口&#xff0c;PS端ARM扩展…

智慧高速公路整体解决方案[76页PPT]

导读&#xff1a;原文《76页智慧高速公路整体解决方案PPPT》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 喜欢文章&#xff0c;您可以关注评论转发本文&#xff0c…

java excel导出 本地运行数据正常 docker或者服务器导出数据为空 已解决

加上这个 response.addHeader("Content-Type","application/octet-stream;charsetutf-8"); 如图

【python爬虫案例】爬了上千条m端微博签到数据

一、爬取目标 大家好&#xff0c;我是马哥python说&#xff0c;一枚10年程序猿。 今天分享一期python爬虫案例&#xff0c;爬取目标是新浪微博的微博签到数据&#xff0c;字段包含&#xff1a; 页码,微博id,微博bid,微博作者,发布时间,微博内容,签到地点,转发数,评论数,点赞数…

Sphinx——Python生成API文档

1、简介 Sphinx是Python文档生成器&#xff0c;它基于reStructuredText标记语言&#xff0c;可自动根据项目生成HTML&#xff0c;PDF等格式的文档&#xff0c;无数著名项目的文档均用Sphinx生成&#xff0c;如机器学习库scikit-learn、交互式神器Jupyter Notebook sphinx是一…

k8s ingress (二)

k8s ingress (二) Ingress介绍 在前面课程中已经提到&#xff0c;Service对集群之外暴露服务的主要方式有两种&#xff1a;NodePort和LoadBalancer&#xff0c;但是这两种方式&#xff0c;都有一定的缺点&#xff1a; NodePort方式的缺点是会占用很多集群机器的端口&#xff0…

常见的时序数据库

1.概念 时序数据库全称为时间序列数据库。时间序列数据库指主要用于处理带时间标签&#xff08;按照时间的顺序变化&#xff0c;即时间序列化&#xff09;的数据&#xff0c;带时间标签的数据也称为时间序列数据。 时间序列数据主要由电力行业、化工行业、气象行业、地理信息…

【高危】Apache Airflow Spark Provider 任意文件读取漏洞 (CVE-2023-40272)

漏洞描述 Apache Airflow Spark Provider是Apache Airflow项目的一个插件&#xff0c;用于在Airflow中管理和调度Apache Spark作业。 受影响版本中&#xff0c;在JDBC连接时&#xff0c;由于没有对conn_prefix参数做验证&#xff0c;允许输入"?"来指定参数。攻击者…

uniapp微信小程序点击右上角菜单分享功能权限配置

个人项目地址&#xff1a; SubTopH前端开发个人站 &#xff08;自己开发的前端功能和UI组件&#xff0c;一些有趣的小功能&#xff0c;感兴趣的伙伴可以访问&#xff0c;欢迎提出更好的想法&#xff0c;私信沟通&#xff0c;网站属于静态页面&#xff09; SubTopH前端开发个人站…

vite 项目搭建

1. 创建 vite 项目 npm create vite@latest 2. 安装sass/less ( 一般我使用sass ) cnpm add -D sasscnpm add -D less 3. 自动导入 两个插件 使用之后,不用导入vue中hook reactive ref cnpm install -D unplugin-vue-components unplugin-auto-import 在 vite.config.…

关闭浏览器窗口弹出提示框(vue项目)

<script> export default {name: App,mounted() { //开发环境不需要提示if (process.env.NODE_ENV development) returnthis.$nextTick(() > {window.addEventListener(beforeunload, this.beforeUnload)})},beforeDestroy() {if (process.env.NODE_ENV development…

手机自动无人直播,实景无人直播真的有用吗?

继数字人直播之后&#xff0c;手机自动直播开始火热了起来&#xff0c;因为其门槛低&#xff0c;成本低&#xff0c;一部手机一个账号就可以实现直播&#xff0c;一时深受广大商家的好评。那么&#xff0c;手机自动无人直播究竟是如何实现自动直播的呢&#xff1f; 在传统的直…

从零做软件开发项目系列之三——系统设计

前言 在与客户充分接触后取得需求调研结果&#xff0c;然后分析调研内容&#xff0c;撰写完成项目的需求规格说明书。这是一个正式的文件&#xff0c;需要供需双方签字确认。说明书中会明确需求方的要求和开发方实现的内容&#xff0c;依据需求规格说明书&#xff0c;开发方就…

uniapp踩坑合集

1、onPullDownRefresh下拉刷新不生效 pages.json对应的style中enablePullDownRefresh设置为true&#xff0c;开启下拉刷新 {"path" : "pages/list/list","style" :{"navigationBarTitleText": "页面标题名称","enable…

数据结构与算法:计算机科学的基石

文章目录 数据结构&#xff1a;构建数据的框架算法&#xff1a;问题的解决方案编程语言&#xff1a;实现数据结构的工具结论 &#x1f389;欢迎来到数据结构学习专栏~数据结构与算法&#xff1a;计算机科学的基石 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&…

Arduino之esp8266

今天&#xff0c;捣鼓了Arduino和esp8266,发现有两款比较好的软件&#xff08;Arduino IDE以及Mixly软件&#xff09;可以将程序下载至esp8266中&#xff0c;而且两者的编程语言都是一样的&#xff0c;都是基于Arduino编程语言&#xff0c;只不过一个Mixly更注重图形编程&#…

芯片验证板卡设计原理图:446-基于VU440T的多核处理器多输入芯片验证板卡

基于VU440T的多核处理器多输入芯片验证板卡 一、板卡概述 基于XCVU440-FLGA2892的多核处理器多输入芯片验证板卡为实现网络交换芯片的验证&#xff0c;包括四个FMC接口、DDR、GPIO等&#xff0c;北京太速科技芯片验证板卡用于完成甲方的芯片验证任务&#xff0c;多任务…

Pandas基础知识

文章目录 Pandas的数据结构Series --- 由数据和索引组成&#xff08;索引&#xff08;index&#xff09;在左&#xff0c;数据&#xff08;values&#xff09;在右&#xff09;DataFrame --- 索引包括行索引和列索引&#xff0c;每列数据可以是不同的类型 Pandas的索引操作 ---…