二叉树 | Java | LeetCode 235 701 450 做题总结,BST特性、 调整二叉树结构(增+删)

235. 二叉搜索树的最近公共祖先

思路:要利用二叉搜索数的性质。当前遍历节点 cur 的数值大于p q时,说明 p q 的父节点在 cur 的左子树。当前遍历节点 cur 的数值小于p q时,说明 p q 的父节点在 cur 的右子树。当前遍历节点 cur 的数值在 p q 之间时,说明 cur 是 p q 的父节点。
cur是公共祖先,他一定是最近的公共祖先吗?是的,一定是。
根本不需要遍历到pq因为二叉搜索树有特性。

  • 出错
错误
Line 23: error: missing return statement
    }
    ^

在这里插入图片描述
这两种写法都是不对的,因为出了if else没有返回值

  • 正确写法
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {  
        if(p.val<root.val && q.val<root.val) {
            return lowestCommonAncestor(root.left, p,q);
        }    
        else if(p.val>root.val && q.val>root.val) {
            return lowestCommonAncestor(root.right, p,q);
        }
         return root;
    }
}

701.二叉搜索树中的插入操作

  • 写错了
class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) {
            TreeNode tmp = new TreeNode(); // TreeNode<Integer>tmp = new TreeNode<>();这里不能这么写
            tmp.val = val;
            root = tmp;
            return root;
        }
        if(val > root.val){
            return insertIntoBST(root.right, val);
        }
        if(val < root.val){
            return insertIntoBST(root.left, val);
        }
    }
}

思路:插入一个节点,一定能放在叶子节点上

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null) {
            TreeNode tmp = new TreeNode(); // TreeNode<Integer>tmp = new TreeNode<>();这里不能这么写
            tmp.val = val;
            return tmp;
        }
        if(val > root.val){
            //插入到他的右节点
            root.right =  insertIntoBST(root.right, val);
        }
        if(val < root.val){
            root.left =  insertIntoBST(root.left, val);
        }
        return root;
    }
}

450.删除二叉搜索树中的节点

1没找到删除的节点
2找到了待删除的节点cur
①cur是叶子节点,直接删除
②cur左子树不为空,右子树为空 => cur 父节点直接指向 cur的 左孩子节点
③cur左空右不空 => cur 父节点直接指向 cur的 右孩子节点
④cur左右都不空,选right右孩子继位(左也行),那么他的左子树放在哪里?放在right左子树最下面的一个
在这里插入图片描述

错误示范

一个函数找目标节点,另一个函数删除可行吗?不可行,因为要返回处理后的树给父节点,要用到递归。

class Solution {
    TreeNode target;
    public TreeNode deleteNode(TreeNode root, int key) {
        //找目标删除节点
        findNode(root, key);
        if(target == null) return null;

        deleteDetail(target);
    }
    public void findNode(TreeNode root, int key) {
        if(key > root.val) {
            findNode(root.right);
        }
        if(key < root.val) {
            findNode(root.left);
        }
        if(key == root.val) {
            target = root;
        }
    }
    public void deleteDetail(TreeNode cur) {
        //叶子节点
        
    }
}

正确答案

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
      return deleteDetail(root,key);
    }

    //怎么表示找不到值为key的节点?
    //这个问题纯纯是题目没看明白,如果二叉树不为空,但找不到为KEY的节点,返回原二叉树
    public TreeNode deleteDetail(TreeNode cur,int key) {
        if(cur == null) {
            return null;
        }

        if(key > cur.val) {
            cur.right = deleteDetail(cur.right, key); //在cur的右子树处理完,返回给右节点
        }
        else if(key < cur.val) {
            cur.left = deleteDetail(cur.left, key);
        }
        if(key == cur.val) {
            //叶子节点
            if(cur.left == null && cur.right == null) {
                return null;
            }
            //只有左子树
            else if(cur.right == null) {
                return cur.left;
            }
            //只有右子树
            else if(cur.left == null) {
                return cur.right;
            }
            //左右孩子都有
            else {
                TreeNode node = cur.right;
                while(node.left!=null) node=node.left;
                node.left = cur.left;
                return cur.right;
            }
        }
        return cur;
    }
}

优化

优化:这种方法会让树的高度变很大,可以找右数最小去替代待删除的节点,只用交换右数最小和删除结点的值,然后就变成了删除右树最小的节点,这个节点一定是个叶子节点,树的结构变化小。

上面说法是B站代码随想录弹幕说的,但经我实践是错误的,因为右树(cur=root.right)最小的节点不一定是个叶子节点,可能没有左子树,那么根节点 cur 就是最小的。交换不了

这个应该可以,但好麻烦啊。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录一个前端axios传参格式的问题

今天改造一个其他系统的页面&#xff0c;直接把原来系统的接口拿过来复用&#xff0c;发现怎么传参都报400&#xff0c;地址参数都一样&#xff0c;怎么就报错了呢&#xff0c;报错原因大概是后台无法解析出参数&#xff08;后台属于其他平台&#xff0c;无法测试&#xff09;。…

python 中关于无法导入自己写的类

python 中关于无法导入自己写的类。解决方法 - Jc_code - 博客园 (cnblogs.com)https://www.cnblogs.com/jc-home/p/12098065.html 加个.就挺好

无中心化崛起:Web3对传统互联网的冲击与重构

随着Web3技术的兴起&#xff0c;传统互联网面临着前所未有的挑战和重构。本文将深入探讨Web3的无中心化特性如何对传统互联网产生冲击&#xff0c;以及其可能带来的重大影响和未来发展趋势。 1. 传统互联网的局限与问题 传统互联网&#xff0c;通常称为Web2&#xff0c;主要依…

利用maven命令往本地仓库添加jar包

一&#xff1a;遇到问题 有些jar包在中央仓库没有&#xff0c;需要手动往本地仓库添加&#xff0c;方便以后打包使用。 比如&#xff1a;添加红框这个依赖&#xff0c;现在爆红 二&#xff1a;解决办法 **第一步&#xff1a;**打开idea&#xff0c;找到运行按钮旁边的框&am…

Guitar Pro如何只播放低声部 Guitar Pro乐队总谱怎么看

在音乐制作与学习过程中&#xff0c;熟练掌握音乐编曲和练习工具至关重要。Guitar Pro作为一款深受吉他爱好者喜爱的专业软件&#xff0c;其强大的功能之一便是能够独立播放乐谱中的各个声部&#xff0c;这对于细致研究和练习低音线条如贝斯线极为有用。下面我们来看看Guitar P…

Flutter 像素编辑器#05 | 缩放与平移

theme: cyanosis 本系列&#xff0c;将通过 Flutter 实现一个全平台的像素编辑器应用。源码见开源项目 【pix_editor】。在前三篇中&#xff0c;我们已经完成了一个简易的图像编辑器&#xff0c;并且简单引入了图层的概念&#xff0c;支持切换图层显示不同的像素画面。 《Flutt…

AVI 是什么格式,AVI 格式用什么播放器打开?

AVI 是什么格式&#xff1f;提到 AVI 格式想必大家多数会想到在 DVD 横行的年代&#xff0c;光盘中所包含的媒体视频格式多是以 AVI 格式存储。AVI 是一个非常通用的容器格式&#xff0c;支持多种视频和音频编解码器。这意味着从DVD中提取视频内容时&#xff0c;可以通过转码为…

第二证券炒股技巧:什么是pe估值法,有哪些优缺点?

1、pe估值法是指即市盈率估值法&#xff0c;是一种上市公司常用的股票估值办法。它通过比较公司的股价与其盈余能力来评估股票的价值&#xff0c;从而判别股票是高估还是轻视。假定公司的盈余能力不再改动&#xff0c;以当时的股价/市值买入这家公司&#xff0c;单纯靠赢利需求…

计算机网络 —— 网络字节序

网络字节序 1、网络字节序 (Network Byte Order)和本机转换 1、大端、小端字节序 “大端” 和” 小端” 表示多字节值的哪一端存储在该值的起始地址处&#xff1b;小端存储在起始地址处&#xff0c;即是小端字节序&#xff1b;大端存储在起始地址处&#xff0c;即是大端字节…

【嵌入式Linux】i.MX6ULL IRQ中断服务函数的编写

文章目录 IRQ中断服务函数流程解释0. 基本流程步骤1. 入口部分2. 读取中断号3. 切换模式并调用C语言处理函数4. 清理和恢复环境5. 完整代码 本文章结合了正点原子的 i.mx6u嵌入式Linux开发指南和笔者的理解。 IRQ中断服务函数流程解释 IRQ Interrupt Request 外部中断 0. 基本…

深度解析:开关电源(DC/DC)与线性电源(LDO)的技术特性与应用差异

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/139955493 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

VS Code 使用 Makefile 运行 CPP项目

Installing the MinGW-w64 toolchainCMake Toolsmakelist.txt报错 1报错 2报错 3生成了 Makefile &#xff0c;如何使用 make 命令 Installing the MinGW-w64 toolchain 参见文档 将 GCC 与 MinGW 结合使用 CMake Tools 参见文档 Linux 上的 CMake 工具入门 CMake 的使用 …

Excel 宏录制与VBA编程 —— 14、使用VBA处理Excel事件

简介 若希望特定事件处理程序在触发特定事件时运行&#xff0c;可以为 Application 对象编写事件处理程序。 Application 对象的事件处理程序是全局的&#xff0c;这意味着只要 Microsoft Excel 处于打开状态&#xff0c;事件处理程序将在发生相应的事件时运行&#xff0c;而不…

AI降痕工具:论文AI率的智能解决方案

告诉大家一个非常残忍的答案&#xff0c;以后所有论文都会被查ai率的。 学术界不仅关注传统的抄袭问题&#xff0c;还增加了一项名为“AIGC检测”的指标。例如知网、维普等平台都能检测论文AI率。 用GPT写论文虽然重复率基本不用担心&#xff0c;但是AI率基本都较高&#xff…

vue3组件通讯-介绍

简介 Vue 3 引入了多种强大的功能和改进&#xff0c;其中包括增强的组件通信机制。了解这些机制对于构建复杂、可维护的应用程序至关重要。下面&#xff0c;我们将介绍在 Vue 3 中组件通信的几种方法。 通讯类型 父子组件通信上下级通信&#xff08;不仅父子级&#xff09;兄…

通用大模型VS垂直大模型——最后还是要双赢

大模型的江湖争霸&#xff1a;通用与垂直&#xff0c;谁会先“拿下一城”&#xff1f; 哎呀&#xff0c;在人工智能这片神奇的沃土上&#xff0c;大模型&#xff08;咱们说的可是那些超级聪明的“大脑”哦&#xff09;正上演着一场别开生面的“武林大会”。一方是全能型选手—…

Java字符串处理深度解析:String、StringBuffer与StringBuilder的奥秘

摘要&#xff1a; 本文将深入探讨Java语言中处理字符串的基础构件&#xff1a;String、StringBuffer和StringBuilder。我们将详细讲解它们的内部原理、适用场景、性能对比以及在现代开发实践中的使用策略。同时&#xff0c;结合当下编程行业的热点技术&#xff0c;如微服务架构…

80、443端口不能开放也能为IP地址申请SSL证书!

IP地址证书作为一种特定的证书&#xff0c;不同于传统的域名验证证书&#xff0c;IP地址证书是通过验证IP地址来确保安全连接。在证书申请过程中&#xff0c;往往要求短暂开放80或者443端口&#xff0c;如果不能开放&#xff0c;IP地址证书则不能签发。 JoySSL提供的IP地址证书…

来聊聊Redis所实现的Reactor模型

写在文章开头 我们都知道解决C10k问题的最好方案就是通过在IO多路复用的基础上通过reactor模型实现高性能的网络并发程序&#xff0c;借助这个设计&#xff0c;redis的主线程也是基于IO多路复用以reactor模型的思路实现了一个高性能的单线程内存数据&#xff0c;本文将带领读者…

使用JAVA代码实现发送订阅消息以及模板消息

今天写了一个商品到货提醒的job任务&#xff0c;具体效果如下 这里用到了微信的发送订阅消息&#xff0c;主要代码是这一块的&#xff0c;最后我把发送了消息的订单存到表里&#xff0c;因为是定时任务&#xff0c;大家可不存 发送订阅消息 | 微信开放文档 /*** 微信平台-商品…