代码随想录算法训练营第20天 | 题目: 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

代码随想录算法训练营第20天 | 题目: 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

文章来源:代码随想录

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

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]

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

示例 1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。
示例 2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
说明:

所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉搜索树中。

第一想法:

使用二叉搜索树的性质,当寻找公共祖先,则公共祖先在[p,q]的区间之中,从根节点遍历判断,大于这个区间则向左,小于则向右,直到存在于这个区间中。

解答思路:

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;}
}

收获:

当是二叉搜索树,其性质找公共祖先节点更容易。

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

给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据保证,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。
在这里插入图片描述

提示:

给定的树上的节点数介于 0 和 10^4 之间
每个节点都有一个唯一整数值,取值范围从 0 到 10^8
-10^8 <= val <= 10^8
新值和原始二叉搜索树中的任意节点值都不同

第一想法:

通过大小判定val插入位置,如果是遍历得到空节点返回插入的节点,返回后根据大小添加在左右子树位置。

解答思路:

1.确定递归函数参数以及返回值
参数就是根节点指针,以及要插入元素,这里递归函数要不要有返回值呢?

可以有,也可以没有,但递归函数如果没有返回值的话,实现是比较麻烦的,下面也会给出其具体实现代码。

有返回值的话,可以利用返回值完成新加入的节点与其父节点的赋值操作。(下面会进一步解释)

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

代码如下:

TreeNode* insertIntoBST(TreeNode* root, int val)

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

代码如下:

if (root == NULL) {TreeNode* node = new TreeNode(val);return node;
}

这里把添加的节点返回给上一层,就完成了父子节点的赋值操作了,详细再往下看。

确定单层递归的逻辑
此时要明确,需要遍历整棵树么?

别忘了这是搜索树,遍历整棵搜索树简直是对搜索树的侮辱。

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

代码如下:

if (root->val > val) root->left = insertIntoBST(root->left, val);
if (root->val < val) root->right = insertIntoBST(root->right, val);
return root;

到这里,大家应该能感受到,如何通过递归函数返回值完成了新加入节点的父子关系赋值操作了,下一层将加入节点返回,本层用root->left或者root->right将其接住。

收获:

遍历边的写法和遍历结点的解法还需要重新区分。

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

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

一般来说,删除节点可分为两个步骤:

首先找到需要删除的节点; 如果找到了,删除它。 说明: 要求算法时间复杂度为 O ( h ) O(h) O(h),h 为树的高度。

示例:
在这里插入图片描述

第一想法:

删除节点的操作更复杂,利用二叉搜索树的性质找到对应的节点,然后列举可能遇到的删除操作。

解答思路:

递归
递归三部曲:

1.确定递归函数参数以及返回值
说到递归函数的返回值,在二叉树:搜索树中的插入操作 (opens new window)中通过递归返回值来加入新节点, 这里也可以通过递归返回值删除节点。

代码如下:

TreeNode* deleteNode(TreeNode* root, int key)

2.确定终止条件
遇到空返回,其实这也说明没找到删除的节点,遍历到空节点直接返回了

if (root == nullptr) return root;

3.确定单层递归的逻辑
这里就把二叉搜索树中删除节点遇到的情况都搞清楚。

有以下五种情况:

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

代码如下:

if (root->val == key) {// 第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点// 第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点if (root->left == nullptr) return root->right;// 第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点else if (root->right == nullptr) return root->left;// 第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置// 并返回删除节点右孩子为新的根节点。else {TreeNode* cur = root->right; // 找右子树最左面的节点while(cur->left != nullptr) {cur = cur->left;}cur->left = root->left; // 把要删除的节点(root)左子树放在cur的左孩子的位置TreeNode* tmp = root;   // 把root节点保存一下,下面来删除root = root->right;     // 返回旧root的右孩子作为新rootdelete tmp;             // 释放节点内存(这里不写也可以,但C++最好手动释放一下吧)return root;}
}

这里相当于把新的节点返回给上一层,上一层就要用 root->left 或者 root->right接住,代码如下:

if (root->val > key) root->left = deleteNode(root->left, key);
if (root->val < key) root->right = deleteNode(root->right, key);
return root;
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;}
}

困难:

这里如果左右子树都存在的节点去除时需要考虑更多,如何具体操作是个问题,需要使用一个while去找到右子树的最左叶子节点。

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

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

相关文章

Centos7部署Mysql8.0超级详细教程,一看就会!

1、准备 下载 Mysql 安装包源信息,去到这个网址&#xff0c;https://dev.mysql.com/downloads/repo/yum/ 复制红色框的内容&#xff0c; 2、开始安装 # 以下所有操作建议切换到 root 用户后运行。。yum install wget -y# 将上面的复制内容粘贴到后面&#xff0c;格式&…

前端性能优化-实测

PageSpeed Insights 性能测试 今天测试网站性能的时候发现一个问题&#xff0c;一个h2标签内容为什么会占据这么长的渲染时间&#xff0c;甚至有阶段测到占据了7000多毫秒&#xff0c;使用了很多方法都不能解决&#xff0c;包括了修改标签&#xff0c;样式大小等&#xff0c;当…

JAVA连接FastGPT实现流式请求SSE效果

FastGPT 是一个基于 LLM 大语言模型的知识库问答系统&#xff0c;提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排&#xff0c;从而实现复杂的问答场景&#xff01; 一、先看效果 真正实流式请求&#xff0c;SSE效果&#xff0c;SSE解释&am…

CentOS7环境下DataX的安装、使用及问题解决

DataX概述 DataX 是阿里巴巴开源的一个异构数据源离线同步工具&#xff0c;致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。 为了解决异构数据源同步问题&#xff0c;DataX将复杂的网状的同步链路变…

eclipse断点调试(用图说话)

eclipse断点调试&#xff08;用图说话&#xff09; debug方式启动项目&#xff0c;后端调试bug调试 前端代码调试&#xff0c;请参考浏览器断点调试&#xff08;用图说话&#xff09; 1、前端 选中一条数据&#xff0c;点击删除按钮 2、后端接口打断点 断点按钮 介绍 resum…

236、二叉树的最近公共祖先

前提&#xff1a; 所有 Node.val 互不相同 。p ! qp 和 q 均存在于给定的二叉树中。 代码如下&#xff1a; class Solution { public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root q || root p || root NULL) return root;TreeN…

.NET周刊【6月第5期 2024-06-30】

国内文章 呼吁改正《上海市卫生健康信息技术应用创新白皮书》 C# 被认定为A 组件 的 错误认知 https://www.cnblogs.com/shanyou/p/18264292 近日&#xff0c;《上海市卫生健康“信息技术应用创新”白皮书》发布&#xff0c;提到医疗信创核心应用适配方法及公立医院信息系统…

书城在线系统:基于Java和SSM框架的高效信息管理平台

开头语&#xff1a;你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM框架&#xff08;Spring, Spring MVC, Mybatis&#xff09; 工具&…

eNSP中WLAN的配置和使用

一、基础配置 1.拓扑图 2.VLAN和IP配置 a.R1 <Huawei>system-view [Huawei]sysname R1 GigabitEthernet 0/0/0 [R1-GigabitEthernet0/0/0]ip address 200.200.200.200 24 b.S1 <Huawei>system-view [Huawei]sysname S1 [S1]vlan 100 [S1-vlan100]vlan 1…

使用瀚高数据库开发管理工具进行数据的备份与恢复---国产瀚高数据库工作笔记008

使用瀚高数据库,备份 恢复数据 然后找到对应的目录 其实就是hgdbdeveloper,瀚高的数据库开发管理工具 对应的包中有个dbclient 这个目录,选中这个目录以后,就可以了,然后 在对应的数据库,比如 data_middle 中,选中 某个模式,比如bigdata_huiju 然后右键进行,点击 恢复,然…

Verilog开源项目——百兆以太网交换机(五)TCAM单元设计

Verilog开源项目——百兆以太网交换机&#xff08;五&#xff09;TCAM单元设计 &#x1f508;声明&#xff1a;未经作者允许&#xff0c;禁止转载 &#x1f603;博主主页&#xff1a;王_嘻嘻的CSDN主页 &#x1f511;全新原创以太网交换机项目&#xff0c;Blog内容将聚焦整体架…

核心实验:基于Web前端的性能测试分析!

实验简介 本实验主要利用IE和Chrome的F12开发人员工具结合Web前端测试分析相关知识&#xff0c;对常见网站进行基于前端的性能测试分析&#xff0c;本实验将不会使用到测试开发相关技术&#xff0c;而是纯粹意义上的手工测试&#xff0c;但却是很容易找到系统前端性能及设计问…

C++字体库开发

建议根据字体需求&#xff0c;多个组合使用。高度定制可基于freeTypeharfbuzz基础库完成。 GitHub - GNOME/pango: Read-only mirror of https://gitlab.gnome.org/GNOME/pango GitHub - googlefonts/fontview: Demo app that displays fonts with a free/libre/open-source …

实用软件分享-----一款免费的投屏软件(支持手机投屏到电脑)Aiseesoft Phone Mirror 2.2.36 x64

专栏介绍:本专栏主要分享一些实用的软件(Po Jie版); 声明1:软件不保证时效性;只能保证在写本文时,该软件是可用的;不保证后续时间该软件能一直正常运行;不保证没有bug;如果软件不可用了,我知道后会第一时间在题目上注明(已失效)。介意者请勿订阅。 声明2:本专栏的…

H616连接摄像头

&#xff08;1&#xff09;首先将USB摄像头连接到OrangePi开发板的USB接口 &#xff08;2&#xff09;通过lsmod命令查看是否加载了uvcvideo模块 lsmod | grep video &#xff08;3&#xff09;通过 v4l2-ctl 命令可以看到 USB 摄像头的设备节点信息为/dev/video0 sudo apt u…

Redis---保证主从节点一致性问题 +与数据库数据保持一致性问题

保证主从节点一致性问题 Redis的同步方式默认是异步的&#xff0c;这种异步的同步方式导致了主从之间的数据存在一定的延迟&#xff0c;因此Redis默认是弱一致性的。 解决&#xff1a; 1.使用Redisson这样的工具&#xff0c;它提供了分布式锁的实现&#xff0c;确保在分布式环…

代码生成器使用指南,JeecgBoot低代码平台

JeecgBoot 提供强大的代码生成器&#xff0c;让前后端代码一键生成&#xff0c;实现低代码开发。支持单表、树列表、一对多、一对一等数据模型&#xff0c;增删改查功能一键生成&#xff0c;菜单配置直接使用。 同时提供强大模板机制&#xff0c;支持自定义模板&#xff0c;目…

Python 基础 (标准库):heapq (堆)

1. 官方文档 heapq --- 堆队列算法 — Python 3.12.4 文档 2. 相关概念 堆 heap 是一种具体的数据结构&#xff08;concrete data structures&#xff09;&#xff1b;优先级队列 priority queue 是一种抽象的数据结构&#xff08;abstract data structures&#xff09;&…

在非 antd pro 项目中使用 umi OpenAPI

大家好&#xff0c;我是松柏。自从跟着鱼皮哥使用了ant design pro中的OpenAPI插件之后&#xff0c;我已经无法忍受自己写请求后端接口的方法了&#xff0c;所以这篇文章记录一下如何在非ant design pro项目中使用OpenAPI。 安装依赖 首先我们需要安装包umijs/openapi&#x…

上交举办“大模型奥林匹克竞赛”,GPT-4o仅得39分

大模型的奥林匹克竞赛来了&#xff01; 最近&#xff0c;上交构建了一个全面、极具挑战性的奥赛级别的基准——OlympicArena&#xff0c;从来自62个不同奥林匹克竞赛中筛选出11,163个问题&#xff0c;涵盖数学、物理、化学、生物、地理、天文学和计算机科学等七个学科&#xf…