二叉搜索树题目:修剪二叉搜索树

news2024/11/26 18:51:59

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:修剪二叉搜索树

出处:669. 修剪二叉搜索树

难度

3 级

题目描述

要求

给定二叉搜索树的根结点 root \texttt{root} root 以及下界 low \texttt{low} low 和上界 high \texttt{high} high,修剪二叉搜索树,使得所有结点的值在 [low,   high] \texttt{[low, high]} [low, high] 中。修剪树不应该改变保留在树中的元素的相对结构 (即任何结点的后代仍然应该作为后代)。可以证明,存在唯一的答案

返回修剪后的二叉搜索树的根结点。注意,根结点可能会根据给定的边界发生改变。

示例

示例 1:

示例 1

输入: root   =   [1,0,2],   low   =   1,   high   =   2 \texttt{root = [1,0,2], low = 1, high = 2} root = [1,0,2], low = 1, high = 2
输出: [1,null,2] \texttt{[1,null,2]} [1,null,2]

示例 2:

示例 2

输入: root   =   [3,0,4,null,2,null,null,1],   low   =   1,   high   =   3 \texttt{root = [3,0,4,null,2,null,null,1], low = 1, high = 3} root = [3,0,4,null,2,null,null,1], low = 1, high = 3
输出: [3,2,null,1] \texttt{[3,2,null,1]} [3,2,null,1]

数据范围

  • 树中结点数目在范围 [1,   10 4 ] \texttt{[1, 10}^\texttt{4}\texttt{]} [1, 104]
  • 0 ≤ Node.val ≤ 10 4 \texttt{0} \le \texttt{Node.val} \le \texttt{10}^\texttt{4} 0Node.val104
  • 树中的每个结点值各不相同
  • root \texttt{root} root 保证是有效的二叉搜索树
  • 0 ≤ low ≤ high ≤ 10 4 \texttt{0} \le \texttt{low} \le \texttt{high} \le \texttt{10}^\texttt{4} 0lowhigh104

解法一

思路和算法

如果二叉搜索树为空,则不需要修剪,返回空树。

如果二叉搜索树不为空,则首先判断根结点值是否在给定的边界范围内,决定根结点是否保留。

  • 如果根结点值大于上界,则根结点的右子树中的所有结点值都大于根结点值,因此都大于上界,根结点和右子树中的所有结点都不保留,修剪后剩余的结点都在根结点的左子树中。

  • 如果根结点值小于下界,则根结点的左子树中的所有结点值都小于根结点值,因此都小于下界,根结点和左子树中的所有结点都不保留,修剪后剩余的结点都在根结点的右子树中。

  • 如果根结点值在给定的边界范围内,则根结点保留,对左子树和右子树分别修剪。

上述过程是一个递归的过程,递归的终止条件是当前结点为空,此时返回空树。对于其余情况,首先判断根结点是否保留,然后对根结点的左子树和右子树调用递归,并用递归调用的结果更新根结点的左子树和右子树。

代码

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if (root == null) {
            return root;
        }
        if (root.val > high) {
            return trimBST(root.left, low, high);
        }
        if (root.val < low) {
            return trimBST(root.right, low, high);
        }
        root.left = trimBST(root.left, low, high);
        root.right = trimBST(root.right, low, high);
        return root;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉搜索树的结点数。每个结点最多被访问一次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉搜索树的结点数。空间复杂度主要是栈空间,取决于二叉搜索树的高度,最坏情况下二叉搜索树的高度是 O ( n ) O(n) O(n)

解法二

思路和算法

使用迭代实现修剪二叉搜索树,需要首先定位到修剪后的二叉搜索树的根结点,如果新的根结点不为空,则对新的根结点的左子树和右子树执行修剪操作。

从根结点开始遍历。如果当前结点值不在给定的边界范围内,则不保留当前结点,根据当前结点值和边界范围的大小关系决定移动到左子结点或者右子结点,直到当前结点变为空或者当前结点值在给定的边界范围内时,定位到新的根结点。

  • 如果新的根结点为空,则返回空树。

  • 如果新的根结点不为空,则对新的根结点的左子树和右子树执行修剪操作。

修剪左子树时,由于左子树中的所有结点值都小于根结点值,因此需要判断左子树中的每个结点值是否小于下界。将父结点初始化为新的根结点,将当前结点初始化为左子树的根结点。修剪操作如下。

  • 如果当前结点值小于下界,则不保留当前结点和当前结点的左子树,因此将当前结点移动到当前结点的右子结点,将父结点的左子结点设为更新后的当前结点。

  • 如果当前结点值大于等于下界,则保留当前结点,因此将父结点移动到当前结点,将当前结点移动到当前结点的左子结点。

修剪右子树时,由于右子树中的所有结点值都大于根结点值,因此需要判断右子树中的每个结点值是否大于上界。将父结点初始化为新的根结点,将当前结点初始化为右子树的根结点。修剪操作如下。

  • 如果当前结点值大于上界,则不保留当前结点和当前结点的右子树,因此将当前结点移动到当前结点的左子结点,将父结点的右子结点设为更新后的当前结点。

  • 如果当前结点值小于等于上界,则保留当前结点,因此将父结点移动到当前结点,将当前结点移动到当前结点的右子结点。

代码

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        while (root != null) {
            if (root.val < low) {
                root = root.right;
            } else if (root.val > high) {
                root = root.left;
            } else {
                break;
            }
        }
        if (root == null) {
            return null;
        }
        TreeNode parentLeft = root, childLeft = root.left;
        while (childLeft != null) {
            if (childLeft.val < low) {
                childLeft = childLeft.right;
                parentLeft.left = childLeft;
            } else {
                parentLeft = childLeft;
                childLeft = childLeft.left;
            }
        }
        TreeNode parentRight = root, childRight = root.right;
        while (childRight != null) {
            if (childRight.val > high) {
                childRight = childRight.left;
                parentRight.right = childRight;
            } else {
                parentRight = childRight;
                childRight = childRight.right;
            }
        }
        return root;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉搜索树的结点数。每个结点最多被访问一次。

  • 空间复杂度: O ( 1 ) O(1) O(1)

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

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

相关文章

SQL-Labs靶场“1-5”关通关教程

君衍. 一、准备工作二、第一关 基于GET单引号字符型注入1、源码分析2、联合查询注入过程 三、第二关 基于GET整型注入1、源码分析2、联合查询注入过程 四、第三关 基于GET单引号变形注入1、源码分析2、联合查询注入过程 五、第四关 基于GET双引号字符型注入1、源码分析2、联合查…

leetcode:416.分割等和子集

解题思路&#xff1a; 转化为01背包问题&#xff0c;集合中每个元素只能用一次&#xff0c;看能不能凑出sum//2这个重量。&#xff08;重量值价值值&#xff09; dp含义&#xff1a;前重量j所获得的最大价值 递推公式&#xff1a;dp[j] max(dp[j],dp[j-numbers[i]] number…

AI嵌入式K210项目(29)-模型加载

文章目录 前言一、下载部署包二、C部署三、搭建文件传输环境四、文件传输五、调试六、MicroPython部署总结 前言 上一章节介绍了如何进行在线模型训练&#xff0c;生成部署包后&#xff0c;本章介绍加载模型&#xff1b; 一、下载部署包 训练结束后&#xff0c;在训练任务条…

幻兽帕鲁 0基础小白如何快速部署服务器

看了许多关于如何部署服务器的&#xff0c;大部分都是要买阿里云或者腾讯云的服务器并且至少四核以上才能保证流畅运行。 但是对于想搭建私服但又没有技术的小白&#xff0c;确实是有点难度了。购买云服务器后还要配置服务器&#xff0c;配置OpenVPN、PalServer&#xff0c;doc…

虚拟机centos7 网络IP冲突

修改其中一个虚拟机IP 1&#xff1a; 设置虚拟机网络配置器的模式为NAT模式&#xff0c;操作方式如下图所示 2&#xff1a;点击虚拟网络编辑器 3&#xff1a;点击NAT设置 4&#xff1a;点击DHCP配置 5&#xff1a; 修改配置文件来指定IP并可以连接到外网&#xff0c;在roo…

基于docker安装HDFS

1.docker一键安装见 docker一键安装 2.拉取镜像 sudo docker pull kiwenlau/hadoop:1.03.下载启动脚本 git clone https://github.com/kiwenlau/hadoop-cluster-docker4.创建网桥 由于 Hadoop 的 master 节点需要与 slave 节点通信&#xff0c;需要在各个主机节点配置节点…

前端技巧之svg精灵图svg-sprite-loader

首先说明精灵图的必要性&#xff0c;其可以让我们只需要向服务器请求一次图片资源&#xff0c;就能加载很多图片&#xff0c;即能够减轻http请求造成的服务器压力。 然后这里要说明的是这个插件是webpack上面的&#xff0c;所以在vue2中比较好用&#xff0c;如果在vue3中&…

RabbitMQ的安装与使用

RabbitMQ的安装与使用 介绍一、RabbitMQ的安装1 查找镜像2 拉取镜像3 查看镜像4 创建容器5 查看容器6 访问测试 二、RabbitMQ的使用1 创建项目2 配置文件3 队列配置文件4 消费者5 生产者6 测试 三、交换器四、普通队列Demo五、死信队列Demo1 介绍2 示例2.1 配置2.2 生产者2.3 消…

Linux下多核CPU指定程序运行的核

设置程序在指定CPU核心运行 一、如何查看程序运行的CPU信息 1.1 查看当前系统CPU有几个核心 查看CPU核心数量&#xff1a;lscpu 1.2 查看程序的PID ps aux|grep cpu_test1.3 查看程序可运行的CPU taskset -c -p pid1.4 设置程序在指定核心上运行 1.4.1 通过运行时的参数设…

Halcon 图像增强(相关算法)

Halcon 图像增强(相关算法) 代码 *****1.读取图片打开窗口**************

【OpenCV学习笔记29】- OpenCV 中的直方图 - 直方图 - 3:2D 直方图

这是对于 OpenCV 官方文档中 图像处理 的学习笔记。学习笔记中会记录官方给出的例子&#xff0c;也会给出自己根据官方的例子完成的更改代码&#xff0c;同样彩蛋的实现也会结合多个知识点一起实现一些小功能&#xff0c;来帮助我们对学会的知识点进行结合应用。 如果有喜欢我笔…

成都力寰璨泓科技有限公司抖音小店购物新体验

在数字化时代&#xff0c;网购已成为人们生活中不可或缺的一部分。随着抖音等短视频平台的兴起&#xff0c;越来越多的消费者选择在抖音小店购物。成都力寰璨泓科技有限公司抖音小店&#xff0c;作为新兴的电商力量&#xff0c;凭借其可靠的品质和服务&#xff0c;正逐渐成为消…

小程序常用组件

一、tabBar tabBar的相关设置要设置在app.json中&#xff08;全局配置&#xff09;。 注意&#xff1a;tabBar中的list是数组形式&#xff0c;每一项都是以对象形式存在&#xff1b; list中对象的数量最多5个&#xff0c;最少2个&#xff1b; list中的对象的pagePath和text是必…

Docker部署Redis哨兵模式

目录结构 先按照这个目录结构创建。 redis主从配置 redis-master主配置文件 #允许远程连接 bind 0.0.0.0# 设置Redis实例的端口号 port 6379# 设置Redis实例的密码 requirepass 123456# 启用持久化 appendonly yes redis-slave1从配置文件 #允许远程连接 bind 0.0.0.0# 设…

ALINX黑金AXU3EGB 开发板用户手册RS485通信接口图示DI RO信号方向标识错误说明

MAX3485这类RS485芯片&#xff0c;DI是TTL信号输入&#xff0c;RO是TTL信号输出 如下图是MAX3485手册规格书。 因此 ALINX黑金AXU3EGB 用户手册 Page 43页 图 3-11-1 PL 端 485 通信的连接示意图&#xff0c;MAX3485芯片的DI RO信号输入输出标识方向是错误的&#xff0c;应为蓝…

【Linux】---Linux下基本指令(2)

目录 一、指令详细介绍1.1 cat 指令1.2 echo 指令1.3 more 指令1.4 less 指令1.5 head 指令1.6 tail 指令1.7 date 指令1.8 cal 指令1.9 find 指令1.10 grep 指令1.11 zip/unzip 指令1.12 tar 指令1.13 uname –r 指令&#xff1a; 一、指令详细介绍 1.1 cat 指令 语法&#…

ABINet原理讲解以及运行

论文地址&#xff1a;https://arxiv.org/pdf/2103.06495.pdf 代码地址&#xff1a;https://github.com/FangShancheng/ABINet 前言 OCR技术经历了是从传统方法到深度学习方法的一个过程&#xff0c;所以在这里我也简述一下传统的OCR技术方法。传统OCR方法在简单场景下效果良…

算法沉淀——BFS 解决最短路问题(leetcode真题剖析)

算法沉淀——BFS 解决最短路问题&#xff08;leetcode真题剖析&#xff09; 01.迷宫中离入口最近的出口02.最小基因变化03.单词接龙04.为高尔夫比赛砍树 BFS&#xff08;广度优先搜索&#xff09;是解决最短路径问题的一种常见算法。在这种情况下&#xff0c;我们通常使用BFS来…

智胜未来,新时代IT技术人风口攻略-第五版(弃稿)

文章目录 前言鸿蒙生态科普调研人员画像高校助力鸿蒙高校鸿蒙课程开设占比教研力量并非唯一原因 企业布局规划全盘接纳仍需一段时间企业对鸿蒙的一些诉求 机构入场红利机构鸿蒙课程开设占比机构对鸿蒙的一些诉求 鸿蒙实际体验高校用户群体场景分析企业用户群体场景分析培训机构…

东方博宜 1395. 小丽找数?

东方博宜 1395. 小丽找数&#xff1f; #include<iostream> using namespace std; int main() {int x ;cin >> x ;int cnt 0 ;for (int i 1 ; i < x ; i){ int y i ;int sum 0;while(y > 0){sum y%10 ;y / 10 ;}if(sum%5!0 &&sum%2!0)cnt 1 …