算法打卡day19|二叉树篇08|Leetcode 235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

算法题

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

题目链接:235. 二叉搜索树的最近公共祖先

大佬视频讲解:二叉搜索树的最近公共祖先视频讲解

个人思路

昨天做过一道二叉树的最近公共祖先,而这道是二叉搜索树,那就要好好利用这个有序的特点来解决这道题,因为是有序树,所以如果 中间节点是 q 和 p 的公共祖先,那么 中节点的数组 一定是在 [p, q]区间的。即 中节点 > p && 中节点 < q 或者 中节点 > q && 中节点 < p。

解法
递归法

那么只要从上到下去遍历,遇到 cur节点是数值在[p, q]区间中则一定可以说明该节点cur就是p 和 q的公共祖先。但一定是最近公共祖先吗?画个图看看

如图下,从根节点搜索,第一次遇到 cur节点是数值在[q, p]区间中,即 节点7,此时可以说明 q 和 p 一定分别存在于 节点 7的左子树,和右子树中。

所以从上向下去递归遍历,第一次遇到 cur节点是数值在[q, p]区间中,那么cur就是 q和p的最近公共祖先.

这道题和二叉树的搜索还有一点不同,就是本题就是标准的搜索一条边的写法,遇到递归函数的返回值,如果不为空,立刻返回

再加上这道题没有递归顺序,因为这里没有中节点的处理逻辑;递归函数就很简单了如下

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if (root.val > p.val && root.val > q.val) //终止条件{return lowestCommonAncestor(root.left, p, q);}//递归过程if (root.val < p.val && root.val < q.val) {return lowestCommonAncestor(root.right, p, q);}return root;//返回参数}
}

时间复杂度:O(n);(遍历整棵树)

空间复杂度:O(n);(递归树的高度,如果是一个高度不平衡的树(例如链状结构)高度与n接近)

迭代法

和递归法思路相似,改成了while循环,找到最近公共祖先就返回节点;

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {while (true) {//遍历选择方向   if (root.val > p.val && root.val > q.val) {//若大了,就往小的方向靠即树的左边root = root.left;} else if (root.val < p.val && root.val < q.val) {root = root.right;} else {break;}}return root;}
}

时间复杂度:O(n);(遍历整棵树)

空间复杂度:O(1);(只有一个节点)


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

题目链接:701.二叉搜索树中的插入操作

大佬视频讲解:二叉搜索树中的插入操作视频讲解

个人思路

因为说还可以重构二叉树,一时间不知道怎么下手

解法
递归法

可以不考虑题目中提示所说的改变树的结构的插入方式,只考虑如何插入节点,只要按照二叉搜索树的规则去遍历,遇到空节点就插入节点就可以了。

递归三步走:

1.确定递归函数参数以及返回值

参数就是根节点指针,以及要插入元素,

递归函数需要有返回值,可以利用返回值完成新加入的节点与其父节点的赋值操作

递归函数的返回类型为节点类型TreeNode *

2.确定终止条件

终止条件就是找到遍历的节点为null的时候,就是要插入节点的位置了,并把插入的节点返回。

3.确定单层递归的逻辑

搜索树是有方向了,可以根据插入元素的数值,决定递归方向。

class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {// 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。if (root == null) { return new TreeNode(val);}if (root.val < val){root.right = insertIntoBST(root.right, val); // 递归创建右子树}else if (root.val > val){root.left = insertIntoBST(root.left, val); // 递归创建左子树}return root;}
}

时间复杂度:O(n);(最差遍历一遍树)

空间复杂度:O(n);(递归树的高度,如果是一个高度不平衡的树(例如链状结构)高度与n接近)

迭代法

迭代的方法就需要记录当前遍历节点的父节点了,这个和没有返回值的递归函数实现的代码逻辑是一样的。

class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {if (root == null) return new TreeNode(val);TreeNode newRoot = root;TreeNode pre = root;//父节点while (root != null) {pre = root;if (root.val > val) {//利用二叉树特点root = root.left;} else if (root.val < val) {root = root.right;} }//当root为空时,就找到了插入节点的位置,再根据值的大小选择插入左边还是右边if (pre.val > val) {pre.left = new TreeNode(val);} else {pre.right = new TreeNode(val);}return newRoot;}
}

时间复杂度:O(n);(遍历整棵树)

空间复杂度:O(1);(因为是原地修改树的方式进行插入,不涉及递归调用栈的空间增长;除了返回的新节点外,算法不需要额外的空间来存储任何信息)


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

题目链接:450.删除二叉搜索树中的节点

大佬视频讲解:删除二叉搜索树中的节点视频讲解

个人思路

思路不清晰,主要是如何在删除节点后有多少种情况要解决不太明白

解法
递归法

因为二叉搜索树添加节点只需要在叶子上添加就可以的,不涉及到结构的调整,而删除节点操作涉及到结构的调整。这里使用递归函数的返回值来完成把节点从二叉树中移除的操作。

递归三步走:

1.确定递归函数参数以及返回值

上道题是通过递归返回值来加入新节点, 这里也可以通过递归返回值删除节点

2.确定终止条件

遇到空返回,其实这也说明没找到删除的节点,遍历到空节点直接返回了

3.确定单层递归的逻辑

二叉搜索树中删除节点遇到的情况有以下五种情况

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

其中第五种情况比较难理解,画图理解,如下。

class Solution {public TreeNode deleteNode(TreeNode root, int key) {if (root == null) return root;//终止条件if (root.val == key) {//找到删除节点if (root.left == null) {return root.right;} else if (root.right == null) {return root.left;} else {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;}
}

时间复杂度:O(n);(遍历二叉树)

空间复杂度:O(n);(递归树的高度,如果是一个高度不平衡的树(例如链状结构)高度与n接近)

 迭代法

用迭代法模拟递归法中的逻辑来删除节点,但需要一个pre记录cur的父节点方便做删除操作

class Solution {public TreeNode deleteNode(TreeNode root, int key) {if (root == null){return null;}//寻找对应的对应的前面的节点,以及他的前一个节点TreeNode cur = root;TreeNode pre = null;//父节点while (cur != null){if (cur.val < key){pre = cur;cur = cur.right;} else if (cur.val > key) {pre = cur;cur = cur.left;}else {break;}}if (pre == null){return deleteOneNode(cur);}if (pre.left !=null && pre.left.val == key){pre.left = deleteOneNode(cur);}if (pre.right !=null && pre.right.val == key){pre.right = deleteOneNode(cur);}return root;}public TreeNode deleteOneNode(TreeNode node){//处理删除节点的情况if (node == null){return null;}if (node.right == null){return node.left;}TreeNode cur = node.right;while (cur.left !=null){cur = cur.left;}cur.left = node.left;return node.right;}}

时间复杂度:O(n);(遍历二叉树)

空间复杂度:O(1);(因为是原地修改树的方式进行插入,不涉及递归调用栈的空间增长;除了返回的新节点外,算法不需要额外的空间来存储任何信息)


以上是个人的思考反思与总结,若只想根据系列题刷,参考卡哥的网址代码随想录算法官网

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

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

相关文章

zed2i相机驱动的安装(2)

安装完sdk和wrapper&#xff0c;启动时显示缺少标定文件&#xff0c;第一反应是运行自带的标定程序 但是此时运行ZED tools里的标定程序也会出问题 打开 On Linux : /usr/local/zed/settings/On Windows : C:\ProgramData\Stereolabs\settings 查看里面是否是空的&#xff…

Android系统签名的制作与使用

目录 1. &#x1f4c2; 背景 2. &#x1f531; 制作Android系统签名 步骤一&#xff1a;找到platform.pk8和platform.x509.pem签名文件 步骤二&#xff1a;下载keytool-importkeypair签名工具 步骤三&#xff1a;使用签名文件和签名工具生成.jks签名文件 3. ✅ 使用Andro…

嵌入空间(Embedding Space)

摘要&#xff1a; 嵌入空间&#xff08;Embedding Space&#xff09;是一种在数学、机器学习和自然语言处理等领域广泛应用的概念。它指的是将原本复杂、离散或者高维的数据结构转换为一个连续的、低维向量空间的过程&#xff0c;使得这些数据能够在新的空间中以向量的形式表示…

AI_寻路系统_修改寻路网格体__下

虚幻引擎的 寻路系统&#xff08;Navigation System&#xff09; 向人工智能代理提供了寻路功能。为了能够找到开始位置和目的地之间的路径&#xff0c;从世界的碰撞几何结构生成了寻路网格体。 默认设置将寻路网格体细分为图块&#xff0c;以允许重建寻路网格体的本地化部件。…

FFplay播放参数详解决及示例

1. -version 查看版本 2. -buildconf 查看编译配置 3. -formats 显示所有支持的媒体格式 4. -muxers 查看所有的封装 5. -demuxers 查看所有支持的解封装

webots的安装和体验

刚知道webots是一个机器人仿真软件&#xff0c;好像离开硬件可以自己玩玩&#xff0c;而且有人形机器人的源代码&#xff0c;试试看吧。 Cyberbotics: Robotics simulation with Webotshttps://www.cyberbotics.com/ 官网下载&#xff0c;有windows版本&#xff0c;看上去好简…

学习JavaEE的日子 Day27 手撕HashMap底层原理

Day27 1.手撕HashMap底层原理(重点) public class Test01 {public static void main(String[] args) {// Float float1 new Float("0.0f"); // Float float2 new Float("0.0f"); // Float result float1/float2; // System.out.println(result);/…

Airbnb将禁止在房源内安装监控摄像头

在面临隐私问题后&#xff0c;Airbnb 最近更新了政策&#xff0c;全面禁止房东在出租屋内安装并使用室内安全监控摄像头。 修订后的政策将在全球范围内适用&#xff0c;并将于4 月 30 日生效。Airbnb 表示&#xff0c;做出这一改变是为了优先考虑客人的隐私并简化安全摄像头的规…

Android 13 源码编译及报错修复

下载AOSP指定分支 repo init -u git://aosp../platform/manifest -b android-13.0.0_r83 同步代码到本地 repo sync -c 初始化编译环境, 选择构建目标 source build/envsetup.sh lunch 选择需要构建的目标&#xff0c;此处以aosp_arm64-eng为例 进行固件编译 make -j12 期间编译…

基于Matlab的车牌识别算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

代码随想录算法训练营第25天|16.组合总和III|17.电话号码的字母组合

代码随想录算法训练营第25天|16.组合总和III|17.电话号码的字母组合 216.组合总和III 如果把 组合问题理解了&#xff0c;本题就容易一些了。 题目链接/文章讲解&#xff1a;https://programmercarl.com/0216.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CIII.html 视频讲解&#xf…

代码随想录算法训练营第41天 | 01背包问题(二维+一维) ,416. 分割等和子集

动态规划章节理论基础&#xff1a; https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 01背包理论基础 链接&#xff1a;https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%…

【Linux C | 多线程编程】线程的基础知识

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

【Linux系列】计算机系统中的架构与发行版:理解与区分

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

软件测试 自动化测试selenium 基础篇

文章目录 1. 什么是自动化测试&#xff1f;1.1 自动化分类 2. 什么是 Selenium &#xff1f;3. 为什么使用 Selenium &#xff1f;4. Selenium 工作原理5. Selenium 环境搭建 1. 什么是自动化测试&#xff1f; 将人工要做的测试工作进行转换&#xff0c;让代码去执行测试工作 …

使用PWM实现呼吸灯功能

CC表示的意思位捕获比较&#xff0c;CCR表示的是捕获比较寄存器 占空比等效于PWM模拟出来的电压的多少&#xff0c;占空比越大等效出的模拟电压越趋近于高电平&#xff0c;占空比越小等效出来的模拟电压越趋近于低电平&#xff0c;分辨率表示的是占空比变化的精细程度&#xf…

ChatGPT GPT4科研应用、数据分析与机器学习、论文高效写作、AI绘图技术

原文链接&#xff1a;ChatGPT GPT4科研应用、数据分析与机器学习、论文高效写作、AI绘图技术https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247596849&idx3&sn111d68286f9752008bca95a5ec575bb3&chksmfa823ad6cdf5b3c0c446eceb5cf29cccc3161d746bdd9f2…

【C++】类和对象终章

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、初始化列表1.1 初始化列表的形式1.2 初始化列表的注意事项 二、explicit关键…

Halcon识别文字案例

识别文字并显示到页面上 read_image (Image, needle1.png) * 打开窗口 dev_open_window (0, 0, 512, 512, black, WindowHandle) dev_display (Image)* 画矩形 gen_rectangle1 (ROI_0, 52.4648, 99.0391, 256.758, 354.063) * 裁剪 reduce_domain (Image, ROI_0, ImageReduced)…

Unity Live Capture 中实现面部捕捉同步模型动画

Unity Face Capture 是一个强大的工具&#xff0c;可以帮助你快速轻松地将真实人脸表情捕捉到数字模型中。在本文中&#xff0c;我们将介绍如何在 Unity Face Capture 中实现面部捕捉同步模型动画。 安装 |实时捕获 |4.0.0 (unity3d.com) 安装软件插件 安装 Live Capture 软件…