当前位置: 首页 > news >正文

代码随想录算法训练营第二十天(二叉树 七)

day19 周日放假 今天依旧是二叉树环节

力扣题部分:

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

题目链接:. - 力扣(LeetCode)

题面:

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

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

思路:

        和day18的二叉树公共祖先不同的是,这一次我们可以利用二叉搜索树的特点遍历一个路径就够了,其他的倒没什么太大区别。

具体思路细节内容可以看day18的最后一题 236. 二叉树的最近公共祖先,这里就不重复了。

传送门(day18):代码随想录算法训练营第十八天(二叉树 六)-CSDN博客

代码实现:

class Solution {
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if(p -> val > q -> val) swap(q, p);if(root -> val >= p -> val && root  -> val <= q -> val) return root;if(root -> val < p -> val && root -> right) return lowestCommonAncestor(root -> right, p, q);if(root -> val > q -> val && root -> left) return lowestCommonAncestor(root -> left, p, q);return nullptr;}
};

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

题目链接:. - 力扣(LeetCode)

题面:

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

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

思路:

        按照最简单的想法,一条路径走到底最后创造一个叶子节点挂树上就好了,可以不重构二叉树就不要重构二叉树了,不然就很麻烦(就像下一道题)。

代码实现:

class Solution {
public:TreeNode* insertIntoBST(TreeNode* root, int val) {if(!root){TreeNode* newnode = new TreeNode(val);return newnode;}if(root -> val > val) root -> left = insertIntoBST(root -> left, val);if(root -> val < val) root -> right = insertIntoBST(root -> right, val);return root;}
};

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

题目链接:. - 力扣(LeetCode)

题面:

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

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

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。

思路:

        我们知道插入可以插入在叶子节点也可以不插入在叶子节点,而删除就没得选择,所有情况都要考虑,那就得按需要删除的结点情况分类讨论了:

1.没找到。

        解决办法:遍历到空节点直接返回。

2.找到了,在叶子节点上。

        解决办法:删除节点并返回空节点。

3.找到了,左边有子树右边没有。

        解决办法:像链表一样,要删除的节点的父节点指向要删除节点的左节点,相当于绕过要删除的节点,然后记得删除释放空间。

4.找到了,右边右子树左边没有。

        解决办法:第三条类似,父节点指向删除节点的右节点。

5.找到了,左右两边都有子树。

        解决办法:最难的部分。先讲操作:将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点

我们知道二叉搜索树要保证中序遍历递增,删除节点的左子树全部比右子树小,该节点一删右节点像之前一样一补上去,整个左子树就悬空了,由于左子树都比右子树小,所以只能把悬空的左子树根节点放在右节点最小的节点左侧,这样就可以让中序遍历仍旧是递增的了。(如果还有点懵,可以尝试画个图自己手动删除节点理解一下)

代码实现:

class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {if (root == nullptr) return root; // 第一种情况if (root->val == key) {// 第二种情况if (root->left == nullptr && root->right == nullptr) {delete root;return nullptr;}// 第三种情况else if (root->left == nullptr) {auto retNode = root->right;delete root;return retNode;}// 第四种情况else if (root->right == nullptr) {auto retNode = root->left;delete root;return retNode;}// 第五种情况else {TreeNode* cur = root->right; // 找右子树最左面的节点while(cur->left != nullptr) {cur = cur->left;}cur->left = root->left;TreeNode* tmp = root;root = root->right;delete tmp;return root;}}if (root->val > key) root->left = deleteNode(root->left, key);if (root->val < key) root->right = deleteNode(root->right, key);return root;}
};

http://www.lryc.cn/news/430247.html

相关文章:

  • Django 后端架构开发:通用表单视图、组件对接、验证机制和组件开发
  • Cookie和Session是什么?它们的区别是什么?
  • Python正则表达式提取车牌号
  • 视觉引导机械臂学习记录
  • 插屏广告在游戏APP中广告变现的独特优势
  • Python数据分析:数据可视化(Matplotlib、Seaborn)
  • Java CompletableFuture:你真的了解它吗?
  • 5个免费在线 AI 绘画网站推荐,附100+提示词!
  • C++基础语法:while的使用
  • 鹏哥C语言自定义笔记重点(29-)
  • 代码随想录算法训练营第六十天 | dijkstra(堆优化版)、Bellman_ford 算法精讲
  • boost::asio 库版本,C/C++代码编译兼容性
  • 前端开发的项目导入方法与应用
  • C++:模拟实现string
  • 浅谈Kafka(一)
  • Redis7基础篇(八)
  • Tauri简介
  • JavaWeb——MVC架构模式
  • Excel求和方法之
  • Windows Server 域控制服务器安装及相关使用
  • linux基础命令(超级详细)
  • 大模型笔记之-XTuner微调个人小助手认知
  • 用TensorFlow实现线性回归
  • IT计算机软件系统类毕业论文结构指南:从标题到结论的全景视角
  • leetcode27:移除元素(正解)
  • docker部署nginx--(部署静态文件和服务)
  • websocket的介绍及springBoot集成示例
  • 软件测试-自动化测试
  • Linux 安装TELEPORT堡垒机
  • 【14】即时编译器的中间表达形式