6.23删除二叉搜索树中的节点(LC450-M)

news2024/11/16 13:53:18

算法:

一共有五种可能的情况:

  • 第一种情况:没找到删除的节点,遍历到空节点直接返回了
  • 找到删除的节点
    • 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
    • 第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点
    • 第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
    • 第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。

第五种情况,比如要删除节点7,可以让它的左孩子或者右孩子去继位。这里是让左孩子去继位,左孩子比7小,右孩子比7大,那左孩子应该继位在右孩子的最小的节点的左边,即8左边。然后,让3指向9。

调试过程:

/**
 * 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 deleteNode(TreeNode root, int key) {        
        if (root == null) return root;
//1.找不到key节点,自动返回原root
        if (root.val == key) {
//2.左右都空,说明是叶子,直接删除
        if (root.left==null && root.right==null) return null;
//3.左空右不空,右上移
        if (root.left==null && root.right!=null) {
            root = root.right;
            return root;
        }
//4.右空左不空,左上移        
        if (root.left!=null && root.right==null) {
            root = root.left;
            return root;
        }
//5.左右都不空,root的左孩子移到右孩子的最左边
        if (root.left!=null && root.right!=null){
            TreeNode left = root.left;
            root = root.right;
            while (root.left!=null){
                root = root.left;
            }
            root.left = left;
            return root;
        }
        }
        if (root.val < key) deleteNode(root.left, key);  
        if (root.val > key) deleteNode(root.right, key);      
        return root;

    }
}

原因:

左右都不空时,代码有问题。

代码逻辑不对,没有中间变量cur,相当于少了个变量cur去实现交换操作。

而且,递归处没有赋值给root.left和root.right(因为这里的递归是有返回值TreeNode的)!!!!无法真正实现递归(这一点老是忘记)

修改后:

/**
 * 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 deleteNode(TreeNode root, int key) {        
        if (root == null) return root;
//1.找不到key节点,自动返回原root
        if (root.val == key) {
//2.左右都空,说明是叶子,直接删除
        if (root.left==null && root.right==null) return null;
//3.左空右不空,右上移
        if (root.left==null && root.right!=null) {
            root = root.right;
            return root;
        }
//4.右空左不空,左上移        
        if (root.left!=null && root.right==null) {
            root = root.left;
            return root;
        }
//5.左右都不空,root的左孩子移到右孩子的最左边
        if (root.left!=null && root.right!=null){
            TreeNode cur = root.right;
            while (cur.left!=null){
                cur = cur.left;
            }
            cur.left = root.left;
            root = root.right;
            return root;
        }
        }
        if (root.val < key) root.left=deleteNode(root.left, key);  
        if (root.val > key) root.right=deleteNode(root.right, key);      
        return root;

    }
}

原因:

递归处逻辑不对。

应该是key比root.val小时,向左搜索

应该是key比root.val大时,向右搜索

正确代码:

/**
 * 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 deleteNode(TreeNode root, int key) {        
        if (root == null) return root;
//1.找不到key节点,自动返回原root
        if (root.val == key) {
//2.左右都空,说明是叶子,直接删除
        if (root.left==null && root.right==null) return null;
//3.左空右不空,右上移
        if (root.left==null && root.right!=null) {
            root = root.right;
            return root;
        }
//4.右空左不空,左上移        
        if (root.left!=null && root.right==null) {
            root = root.left;
            return root;
        }
//5.左右都不空,root的左孩子移到右孩子的最左边
        if (root.left!=null && root.right!=null){
            TreeNode cur = root.right;
            while (cur.left!=null){
                cur = cur.left;
            }
            cur.left = root.left;
            root = root.right;
            return root;
        }
        }
        if (key< root.val) root.left=deleteNode(root.left, key);  
        if (key> root.val) root.right=deleteNode(root.right, key);      
        return root;

    }
}

时间空间复杂度:

时间复杂度:

O(n),其中 n为 root的节点个数。最差情况下,寻找和删除 cur各需要遍历一次树。

空间复杂度:

O(n),其中 n为 root的节点个数。递归的深度最深为 O(n)。

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

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

相关文章

鸿蒙4.0开发 - DevEco Studio如何使用Previewer窗口预览器报错

DevEco Studio预览器概况在HarmonyOS应用开发过程中&#xff0c;通过使用预览器&#xff0c;可以查看应用的UI效果&#xff0c;方便开发者实时查看应用的运行效果&#xff0c;随时调整代码。 1.正常启动 打开预览器的位置在DevEco Studio编辑界面的右上角部分&#xff0c;竖排…

基于VGG-16+Android+Python的智能车辆驾驶行为分析—深度学习算法应用(含全部工程源码)+数据集+模型(三)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据预处理2. 模型构建3. 模型训练及保存1&#xff09;模型训练2&#xff09;模型保存 4. 模型生成1&#xff09;模型导入及调用2&#xff09;相关代码&#xff08;1&#xff09;布局文件&#xff08;2&#xff…

独立站低成本流量:优化用户体验,实现精准营销

在当今的数字化时代&#xff0c;获取流量是每个网站成功的关键。然而&#xff0c;随着竞争的加剧&#xff0c;流量获取的成本也在逐渐上升。对于许多独立站来说&#xff0c;如何低成本的获取流量变得越来越具有挑战性。本文Nox聚星将和大家探讨独立站如何通过网站优化和精准营销…

云演CTF Blog

1、啥也搞不了&#xff0c;扫目录。出来个console 2、有显示锁掉了 3、抓包&#xff0c;改返回包 改成true&#xff0c;放包 不好意思&#xff0c;不会了&#xff0c;哈哈哈哈哈哈哈哈哈 你会的话&#xff0c;请告诉我&#xff0c;大佬

软实力篇---第四篇

系列文章目录 文章目录 系列文章目录前言一、你对我们公司有什么想问的吗?二、很多人都倒在自我介绍上三、如何与 HR 交谈,如何谈薪水前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就…

docker consul容器的自动发现与注册

一、微服务&#xff08;容器&#xff09;的注册与发现——微服务架构中极其重要的组件 1、定义&#xff1a;是一种分布式管理系统以及定位服务的方法。传统架构中&#xff0c;应用程序之间直连到已知的服务&#xff0c;设备提供的网络&#xff08;IP地址&#xff09;&#xff…

揭开机器学习转换器架构的神秘面纱

自2017年推出以来&#xff0c;转换器&#xff08;Transformers&#xff09;已成为机器学习领域的一支突出力量&#xff0c;彻底改变了专业翻译和自动完成服务的能力。 最近&#xff0c;随着OpenAI公司的ChatGPT和Meta公司的LLama等大型语言模型的出现&#xff0c;转换器的受欢…

保障线程安全性:构建可靠的多线程应用

目录 引言 为什么线程安全性如此重要&#xff1f; 1. 竞态条件&#xff08;Race Conditions&#xff09; 2. 死锁&#xff08;Deadlocks&#xff09; 3. 数据竞争&#xff08;Data Races&#xff09; 4. 内存可见性&#xff08;Memory Visibility&#xff09; 面临的挑战…

【网络安全技术】电子邮件安全PGP,SMIME

一、PGP&#xff08;Pretty Good Privacy&#xff09; PGP是一种邮件加密手段&#xff0c;他在发邮件一方加密&#xff0c;然后发给发送方邮件服务器&#xff0c;发送方邮件服务器再发送给接收方邮件服务器&#xff0c;然后接收方再从接收方邮件服务器pop出来&#xff0c;这整…

Axure动态面板的应用与ERP系统登录界面、主页左侧菜单栏、公告栏的绘制

目录 一、动态面板 1.1 简介 1.2 使用动态面板的原因 二、动态面板之轮播图实现案例 2.1 完成步骤 2.2 最终效果 三、动态面版之多方式登录案例 四、动态面板之后台主界面左侧菜单栏 五、ERP登录界面 六、ERP主界面菜单栏 七、ERP公告栏 八、登录页面跳转公告栏 一…

OpenAI开源超级对齐方法:用GPT-2,监督、微调GPT-4

12月15日&#xff0c;OpenAI在官网公布了最新研究论文和开源项目——如何用小模型监督大模型&#xff0c;实现更好的新型对齐方法。 目前&#xff0c;大模型的主流对齐方法是RLHF&#xff08;人类反馈强化学习&#xff09;。但随着大模型朝着多模态、AGI发展&#xff0c;神经元…

【专栏目录】

摘要 本专栏是讲解如何改进RT-DETR的专栏。改进方法采用了最新的论文提到的方法。改进的方法包括&#xff1a;增加注意力机制、更换卷积、更换block、更换backbone、更换head、更换优化器等&#xff1b;每篇文章提供了一种到N种改进方法。 评测用的数据集是我自己标注的数据集…

【设计模式--行为型--中介者模式】

设计模式--行为型--中介者模式 中介者模式定义结构案例实现优缺点使用场景 中介者模式 定义 又叫调停模式&#xff0c;定义一个中介角色来封装一系列对象之间的交互&#xff0c;使原有对象之间的耦合松散&#xff0c;且可以独立的改变它们之间的交互。 结构 抽象中介者角色…

【Vue】elementUI表格,导出Excel

系列文章 【Vue】vue增加导航标签 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/134965353 【Vue】Element开发笔记 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/133947977 【Vue】vue&#xff0c;在Windows IIS平台…

Linux系统编程(二):标准 I/O 库(下)

参考引用 UNIX 环境高级编程 (第3版)嵌入式Linux C应用编程-正点原子 1. 标准 I/O 库简介 标准 I/O 库是指&#xff1a;标准 C 库中用于文件 I/O 操作&#xff08;如&#xff1a;读、写文件等&#xff09;相关的一系列库函数的集合 标准 I/O 库函数相关的函数定义都在头文件 &…

压缩包文件暴力破解 -Server2005(解析)

任务五十一: 压缩包文件暴力破解 任务环境说明:Server2005 1. 通过本地PC中渗透测试平台Kali使用Nmap扫描目标靶机服务版本信息,将 Telnet 版本信息字符串 作为 Flag 提交; flag:Microsoft Windows XP telnetd 2. 通过本地PC中渗透测试平台Kali对服务器场景Windows进行渗透测…

工业交换机的组网方式有哪些?

工业交换机也称作工业以太网交换机&#xff0c;即应用于工业控制领域的以太网交换机设备&#xff0c;由于采用的网络标准&#xff0c;其开放性好、应用广泛以及价格低廉、使用的是透明而统一的TCP/IP协议&#xff0c;以太网已经成为工业控制领域的主要通信标准。 工业交换机的…

JieLink+智能终端操作平台存在弱口令漏洞

产品简介 捷顺JeLink智能终端操作平台(JSOTC2016 fJeLink)是捷顺历经多年行业经验积累&#xff0c;集智能硬件技术视频分析技术、互联网技术等多种技术融合&#xff0c;基于B/S架构&#xff0c;实现核心业务处理模型(用户中心、投权中心财务中心中心值班室、 运维中心车行客户…

大华 DSS 数字监控系统 itcBulletin SQL 注入漏洞复现

0x01 产品简介 大华 DSS 数字监控系统是大华开发的一款安防视频监控系统,拥有实时监视、云台操作、录像回放、报警处理、设备管理等功能。 0x02 漏洞概述 大华 DSS存在SQL注入漏洞,攻击者 /portal/services/itcBulletin 路由发送特殊构造的数据包,利用报错注入获取数据库…

【Spring】07 懒加载

文章目录 1.定义2. 作用3. 配置方式1&#xff09;XML配置2&#xff09;Java配置3&#xff09;注解方式 4. 应用场景5. 注意事项总结 1.定义 懒加载&#xff08;Lazy Initialization&#xff09;是Spring 框架中的一项强大的特性&#xff0c;它允许我们推迟 Bean 的初始化&…