二叉搜索树操作题目:删除二叉搜索树中的结点

文章目录

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

题目

标题和出处

标题:删除二叉搜索树中的结点

出处:450. 删除二叉搜索树中的结点

难度

5 级

题目描述

要求

给定二叉搜索树的根结点 root \texttt{root} root 和一个值 key \texttt{key} key,删除二叉搜索树中的值为 key \texttt{key} key 的结点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根结点的引用。

一般而言,删除结点可分为两个步骤:

  1. 首先找到需要删除的结点。
  2. 如果找到了需要删除的结点,删除该结点。

示例

示例 1:

示例 1.1

输入: root = [5,3,6,2,4,null,7], key = 3 \texttt{root = [5,3,6,2,4,null,7], key = 3} root = [5,3,6,2,4,null,7], key = 3
输出: [5,4,6,2,null,null,7] \texttt{[5,4,6,2,null,null,7]} [5,4,6,2,null,null,7]
解释:给定需要删除的结点值是 3 \texttt{3} 3,所以我们首先找到值为 3 \texttt{3} 3 的结点,然后删除它。
一个正确的答案是 [5,4,6,2,null,null,7] \texttt{[5,4,6,2,null,null,7]} [5,4,6,2,null,null,7],如上图所示。
另一个正确的答案是 [5,2,6,null,4,null,7] \texttt{[5,2,6,null,4,null,7]} [5,2,6,null,4,null,7]

示例 1.2

示例 2:

输入: root = [5,3,6,2,4,null,7], key = 0 \texttt{root = [5,3,6,2,4,null,7], key = 0} root = [5,3,6,2,4,null,7], key = 0
输出: [5,3,6,2,4,null,7] \texttt{[5,3,6,2,4,null,7]} [5,3,6,2,4,null,7]
解释:二叉搜索树不包含值为 0 \texttt{0} 0 的结点。

示例 3:

输入: root = [], key = 0 \texttt{root = [], key = 0} root = [], key = 0
输出: [] \texttt{[]} []

数据范围

  • 树中结点数目在范围 [0, 10 4 ] \texttt{[0, 10}^\texttt{4}\texttt{]} [0, 104]
  • -10 5 ≤ Node.val ≤ 10 5 \texttt{-10}^\texttt{5} \le \texttt{Node.val} \le \texttt{10}^\texttt{5} -105Node.val105
  • 每个结点值各不相同
  • root \texttt{root} root 是二叉搜索树
  • -10 5 ≤ key ≤ 10 5 \texttt{-10}^\texttt{5} \le \texttt{key} \le \texttt{10}^\texttt{5} -105key105

进阶

树的高度为 h h h,你是否可以想出时间复杂度为 O ( h ) O(h) O(h) 的解法?

解法一

思路和算法

为了删除二叉搜索树中的结点,需要首先搜索待删除的结点,只有当待删除的结点存在时才需要执行删除结点的操作。

由于在二叉搜索树中搜索特定值的结点是一个递归的过程,因此可以使用递归实现删除结点的操作。递归的终止条件是当前结点为空,此时不需要删除任何结点,返回空二叉树。对于其余情况,比较根结点值和待删除的结点值,决定应该在根结点的哪个子树中删除结点,对该子树调用递归,并用递归调用的结果更新当前结点的相应子树。

  • 如果根结点值大于目标值,则应该在根结点的左子树中删除结点。

  • 如果根结点值小于目标值,则应该在根结点的右子树中删除结点。

  • 如果根结点值等于目标值,则需要删除根结点。判断根结点的左子结点和右子结点是否为空,分别执行相应的操作。

    • 如果根结点的两个子结点都为空,即根结点是叶结点,则直接删除根结点,返回空二叉树。

    • 如果根结点有一个子结点为空,则删除根结点之后剩下非空子树,返回根结点的非空子树。

    • 如果根结点的两个子结点都不为空,则找到根结点的后继结点,后继结点为根结点的右子树中的最右边的结点,将根结点值设为后继结点值,将后继结点设为其右子结点(需要通过对后继结点的父结点更新相应的子结点实现)。

代码

class Solution {public TreeNode deleteNode(TreeNode root, int key) {if (root == null) {return null;}if (root.val > key) {root.left = deleteNode(root.left, key);return root;}if (root.val < key) {root.right = deleteNode(root.right, key);return root;}if (root.left == null && root.right == null) {return null;} else if (root.left == null) {return root.right;} else if (root.right == null) {return root.left;} else {TreeNode node = root.right, parent = root;while (node.left != null) {parent = node;node = node.left;}root.val = node.val;if (parent == root) {parent.right = node.right;} else {parent.left = node.right;}return root;}}
}

复杂度分析

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

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

解法二

思路和算法

递归实现可以改成迭代实现。首先在二叉搜索树中搜索待删除的结点,同时维护待删除的结点的父结点。如果待删除的结点不存在,则不执行删除操作,返回原二叉搜索树。

如果待删除的结点存在,则判断待删除的结点的父结点是否为空结点。如果待删除的结点的父结点为空,则待删除的结点为二叉搜索树的根结点,在整个二叉搜索树中执行删除操作;如果待删除的结点的父结点不为空,则在以待删除的结点为根结点的子树中执行删除操作,然后用执行删除操作之后的结果更新父结点的相应子树。

当原始二叉搜索树或者其中一个子树的根结点为待删除的结点时,删除操作如下。

  • 如果根结点的两个子结点都为空,即根结点是叶结点,则直接删除根结点,返回空二叉树。

  • 如果根结点有一个子结点为空,则删除根结点之后剩下非空子树,返回根结点的非空子树。

  • 如果根结点的两个子结点都不为空,则找到根结点的后继结点,后继结点为根结点的右子树中的最右边的结点,将根结点值设为后继结点值,将后继结点设为其右子结点(需要通过对后继结点的父结点更新相应的子结点实现)。

代码

class Solution {public TreeNode deleteNode(TreeNode root, int key) {TreeNode node = root, parent = null;while (node != null && node.val != key) {parent = node;if (node.val > key) {node = node.left;} else {node = node.right;}}if (node == null) {return root;}if (parent == null) {return deleteRoot(root);} else {if (node == parent.left) {parent.left = deleteRoot(node);} else {parent.right = deleteRoot(node);}return root;}}public TreeNode deleteRoot(TreeNode root) {if (root.left == null && root.right == null) {return null;} else if (root.left == null) {return root.right;} else if (root.right == null) {return root.left;} else {TreeNode parent = root, node = root.right;while (node.left != null) {parent = node;node = node.left;}root.val = node.val;if (node == parent.right) {parent.right = node.right;} else {parent.left = node.right;}return root;}}
}

复杂度分析

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

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

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

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

相关文章

Ubuntu Linux 下安装和卸载cmake 3.28.2版本

一、安装cmake 1.首先&#xff0c;先从cmake官网下载cmake-3.28.2-linux-x86_64.tar.gz 2.用FinalShell 等文件上传工具&#xff0c;将这个压缩包上传到 虚拟机的某个路径去&#xff08;自选&#xff09; 3. cd /usr/local/bin/&#xff0c;然后创建cmake文件夹&#xff0c;…

pnpm : 无法加载文件 D:\tool\nvm\nvm\node_global\pnpm.ps1,因为在此系统上禁止运行脚本

你们好&#xff0c;我是金金金。 场景 新创建的项目&#xff0c;在vscode编辑器终端输入 pnpm i&#xff0c;显示报错如上 解决 在终端输入get-ExecutionPolicy(查看执行策略/权限) 输出Restricted(受限的) 终端再次输入Set-ExecutionPolicy -Scope CurrentUser命令给用户赋予…

STM32低功耗模式

一、低功耗模式介绍 STM32 的低功耗模式有 3 种&#xff1a; 1)睡眠模式&#xff08;CM3 内核停止&#xff0c;外设仍然运行&#xff09; 2)停止模式&#xff08;所有时钟都停止&#xff09; 3)待机模式&#xff08;1.8V 内核电源关闭&#xff09; 在这三种低功耗模式中&#…

Vue3项目封装一个Element-plus Pagination分页

前言:后台系统分页肯定是离不开的,但是ui框架都很多,我们可以定义封装一种格式,所有项目按到这个结构来做. 实例: 第一步:在项目components组件新建一个分页组件,用来进行封装组件. 第二步:根据官方的进行定义,官方提供的这些,需要我们封装成动态模式 第三步:代码改造 <!-…

Unity之第一人称角色控制

目录 第一人称角色控制 &#x1f634;1、准备工作 &#x1f4fa;2、鼠标控制摄像机视角 &#x1f3ae;3、角色控制 &#x1f603;4.杂谈 第一人称角色控制 专栏Unity之动画和角色控制-CSDN博客的这一篇也有讲到角色控制器&#xff0c;是第三人称视角的&#xff0c;以小编…

使用最大边界相关算法处理文章自动摘要

一、需求背景 对于博客或者文章来说&#xff0c;摘要是普遍性的需求。但是我们不可能让作者自己手动填写摘要或者直接暴力截取文章的部分段落作为摘要&#xff0c;这样既不符合逻辑又不具有代表性&#xff0c;那么&#xff0c;是否有相关的算法或者数学理论能够完成这个需求呢&…

【C++】默认成员函数

与普通成员函数差距较大&#xff0c;形式对于我们比较陌生&#xff0c;但这是语法&#xff0c;是我们是必须要掌握的。 目录 类的默认成员函数&#xff1a;构造函数&#xff1a;概念&#xff1a;语法&#xff1a;特性&#xff1a; 析构函数&#xff1a;概念&#xff1a;语法&a…

解决:ModuleNotFoundError: No module named ‘torchvision’

解决&#xff1a;ModuleNotFoundError: No module named ‘torchvision’ 文章目录 解决&#xff1a;ModuleNotFoundError: No module named torchvision背景报错问题报错翻译报错位置代码报错原因解决方法方法一&#xff0c;直接安装方法二&#xff0c;手动下载安装方法三&…

jdk17新特性—— 密封类(Sealed Classes)

目录 一、密封类(Sealed Classes)的概述1.1、概述1.2、特性1.3、注意事项 二、密封类(Sealed Classes)代码示例2.1、密封类(Sealed Classes)代码结构示例2.2、密封类(Sealed Classes)代码示例 三、密封类(Sealed Classes)接口代码示例3.1、密封类(Sealed Classes)接口代码结构示…

微信小程序~上推加载更多组件

本组件使用的是TaroReact 实现的 &#xff0c;具体代码如下 一共分为tsx和less文件 //index.tsx /** RefreshLoading* description 上推加载更多组件* param loading boolean* param style* returns*/import { View } from "tarojs/components"; import React, { FC…

2023蓝帽初赛

APK取证 1.涉案apk的包名是&#xff1f;[答题格式:com.baid.ccs] 用雷电APP智能分析打开 在基本信息里得到应用包名 答案&#xff1a;com.vestas.app 2.涉案apk的签名序列号是&#xff1f;[答题格式:0x93829bd] 同理&#xff0c;在详细信息里面找到了签名序列号 答案&…

nodejs+vue+mysql校园失物招领网站38tp1

本高校失物招领平台是为了提高用户查阅信息的效率和管理人员管理信息的工作效率&#xff0c;可以快速存储大量数据&#xff0c;还有信息检索功能&#xff0c;这大大的满足了用户和管理员这两者的需求。操作简单易懂&#xff0c;合理分析各个模块的功能&#xff0c;尽可能优化界…

立体边界,让arcgis出图更酷炫一些

就是这样子的那个图—— 本期我们还是用长沙市为例&#xff0c; 来手把手的演示制作立体边界&#xff0c; 就是这个样子的边界—— 第一步—准备底图 其实你准备什么底图都可以哈&#xff0c;例如调用天地图、下载个影像图&#xff0c;或者用其他什么的底图&#xff0c;都是…

在ubuntu22.04中借助docker实现安装、调试ros1.0

一.安装docker 参考&#xff1a;https://www.cnblogs.com/cqpanda/p/16247919.html 使用安装方法1直接安装&#xff0c;没出问题&#xff0c;我就继续了。出问题按方法2安装吧。 curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 二.docker中安装ros1.…

基于微信小程序+Springboot线上租房平台设计和实现【三端实现小程序+WEB响应式用户前端+后端管理】

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

【乳腺肿瘤诊断分类及预测】基于PNN概率神经网络

课题名称&#xff1a;基于PNN的乳腺肿瘤诊断分类及预测 版本日期&#xff1a;2023-06-15 运行方式: 直接运行PNN0501.m 文件即可 代码获取方式&#xff1a;私信博主或QQ&#xff1a;491052175 模型描述&#xff1a; 威斯康辛大学医学院经过多年的收集和整理&#xff0c;建…

Selenium处理Alert弹窗

页面弹窗有 3 种类型&#xff1a; alert&#xff08;警告信息&#xff09; confirm&#xff08;确认信息&#xff09; prompt&#xff08;提示输入&#xff09; 对于页面出现的 alert 弹窗&#xff0c;Selenium 提供如下方法&#xff1a; 序号 方法/属性 描述 1 ac…

如何更改Outlook阅读邮件时的默认字体?

如果收到的邮件中未指定字体&#xff0c;outlook默认使用宋体显示。 如果觉得不好看&#xff0c;可以进行更改。但不是在outlook中更改&#xff0c;outlook中只是修改编辑器中的字体&#xff0c;和纯文本邮件浏览的字体&#xff0c;不能更改未指定字体的HTML邮件的显示字体。 …

TensorFlow2实战-系列教程5:猫狗识别2------数据增强

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 猫狗识别1 数据增强 猫狗识别2------数据增强 猫狗识别3------迁移学习 1、猫狗识别任…

C++:CSDN云服务器

每一次打开我的个人中心——&#xff08;T_T&#xff09; 1、右下角加载个不停...... &#xff08;耗时一分钟&#xff09; 2、闪白影...... &#xff08;耗时30秒&#xff09; 3、加载出浏览器...... &#xff08;耗时10秒&#xff09; 4、打开\加载网站...... &#xff0…