代码随想录算法训练营day22 | leetcode 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点
LeetCode 235. 二叉搜索树的最近公共祖先
分析1.0
二叉搜索树根节点元素值大小介于子树之间,所以只要找到第一个介于他俩之间的节点就行
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root.val >= p.val && root.val <= q.val){
return root;
}else if(root.val >= q.val && root.val <= p.val){
return root;
}
else if(root.val >= p.val && root.val >= q.val){
return lowestCommonAncestor(root.left, p, q);
}else{
return lowestCommonAncestor(root.right, p, q);
}
}
}
LeetCode 701.二叉搜索树中的插入操作
分析1.0
搜索树插入的新节点替代了原本的空分叉
find 空分叉 插入
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root == null){
return new TreeNode(val);
}
if(val > root.val){
if(root.right == null){
root.right = new TreeNode(val);
}else {
insertIntoBST(root.right, val);
}
}else{
if(root.left == null){
root.left = new TreeNode(val);
}else {
insertIntoBST(root.left, val);
}
}
return root;
}
}
ps. 这里先确定是左边,再看是否为空的思路挺好
LeetCode 450.删除二叉搜索树中的节点
分析1.0
删除节点,找到节点分情况讨论
- 节点是叶子节点,直接删除
- 节点是分支节点,找左子树的最大值或右子树的最小值节点的pre节点,左树最大值节点可能有左子树,右树最小值节点可能有右子树,pre节点还可能是当前节点
- 有左子树有右子树
- 有左子树无右子树
- 无左子树有右子树
- 删除节点要知道这个节点的父节点 每次递归前先令pre = 当前节点
- 还要清楚待删节点是父节点的左节点还是右节点,设置参数flag指示
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null){
return null;
}
TreeNode pre = new TreeNode(-1);
pre.left = root;
pre.right = root;
return delete(root, key, pre, 0);
}
public TreeNode delete(TreeNode root, int key, TreeNode pre, int flag){
if(root == null){
return null;
}
if(key > root.val){
flag = 1;
pre = root;
delete(root.right, key, pre, flag);
}else if(key < root.val){
flag = -1;
pre = root;
delete(root.left, key, pre, flag);
}else {
// 是叶节点
if(root.left == null && root.right == null){
if(pre.val == -1){
return null;
}
if(flag == -1){
pre.left = null;
}else{
pre.right = null;
}
}
// 分支节点 有左子树没右子树 有左子树有右子树 找左子树最大节点的父节点
else if(root.left != null){
TreeNode target = findLeftTree(root.left, root);
// 如果target是左子树树根-左子树无右子树
int swap = 0;
if(target.val == root.val){
swap = target.left.val;
target.left = root.left.left;
}else{
swap = target.right.val;
// 可能最大节点target.right有左子树
target.right = target.right.left;
}
//System.out.println("pre节点为"+pre.val);
if(flag == -1){
pre.left.val = swap;
}else{
pre.right.val = swap;
}
}
// 分支节点 有右子树没左子树
else if(root.right != null && root.left == null){
TreeNode target = findRightTree(root.right, root);
int swap = 0;
if(target.val == root.val){
swap = target.right.val;
target.right = target.right.right;
}else{
swap = target.left.val;
target.left = target.left.right;
}
//System.out.println("target节点为"+pre.val);
if(flag == -1){
pre.left.val = swap;
}else{
pre.right.val = swap;
}
}
// 分支节点
}
return root;
}
// pre为待删除分支节点 左子树不为空 右子树空 找左子树最大节点
public TreeNode findLeftTree(TreeNode root, TreeNode pre){
//System.out.print("以"+root.val+"为根节点的树的最大节点为");
while(root.right != null){
pre = root;
root = root.right;
}
//System.out.println(root.val+"target节点为"+pre.val);
return pre;
}
// pre为待删除分支节点 右子树不为空 找右子树最小节点
public TreeNode findRightTree(TreeNode root, TreeNode pre){
//System.out.print("以"+root.val+"为根节点的树的最大节点为------");
while(root.left != null){
pre = root;
root = root.left;
}
//System.out.println(root.val+"它的pre节点为"+pre.val);
return pre;
}
}
lieetcode 上看到一个思路
如果目标节点大于当前节点值,则去右子树中删除;
如果目标节点小于当前节点值,则去左子树中删除;
如果目标节点就是当前节点,分为以下三种情况:
其无左子:其右子顶替其位置,删除了该节点;
其无右子:其左子顶替其位置,删除了该节点;
其左右子节点都有:其左子树转移到其右子树的最左节点的左子树上,然后右子树顶替其位置,由此删除了该节点。
总结
- 头脑中要有一棵树,树形象上的特点,遍历序列上的特点
- 一定要先想清楚代码逻辑、循环逻辑、递归逻辑再继续
- 我的做题思维通常都是用代码模拟人脑
常用变量名增量更新
size、val、ans、cnt、cur、pre、next、left、right、index、gap、tar、res、src、len、start、end、flag、ch
代码随想录算法训练营day22 | leetcode 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点的更多相关文章
- [程序员代码面试指南]二叉树问题-在二叉树中找到两个节点的最近公共祖先、[LeetCode]235. 二叉搜索树的最近公共祖先(BST)(非递归)
题目 题解 法一: 按照递归的思维去想: 递归终止条件 递归 返回值 1 如果p.q都不在root为根节点的子树中,返回null 2 如果p.q其中之一在root为根节点的子树中,返回该节点 3 如果 ...
- LeetCode 235. 二叉搜索树的最近公共祖先 32
235. 二叉搜索树的最近公共祖先 235. Lowest Common Ancestor of a Binary Search Tree 题目描述 给定一个二叉搜索树,找到该树中两个指定节点的最近公 ...
- LeetCode 235. 二叉搜索树的最近公共祖先
235. 二叉搜索树的最近公共祖先 题目描述 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先 ...
- Leetcode:235. 二叉搜索树的最近公共祖先
Leetcode:235. 二叉搜索树的最近公共祖先 Leetcode:235. 二叉搜索树的最近公共祖先 Talk is cheap . Show me the code . /** * Defin ...
- Java实现 LeetCode 235 二叉搜索树的最近公共祖先
235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个 ...
- 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q ...
- 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 + 二叉排序树 + 最近公共祖先
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 Offer_68_1 题目描述 方法一:迭代法 由于该题的二叉树属于排序二叉树,所以相对较简单. 只需要判断两个结点是否在根节点的左右子树中 ...
- [LeetCode] 235. Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最近公共祖先
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...
- leetcode 235. 二叉搜索树的最近公共祖先(c++)
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x ...
- 利用Tarjan算法解决(LCA)二叉搜索树的最近公共祖先问题——数据结构
相关知识:(来自百度百科) LCA(Least Common Ancestors) 即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. 例如: 1和7的最近公共祖先为5: 1和5的 ...
随机推荐
- Task01:Matplotlib初相识
一.明晰绘制一张图的组成条件 Figure:最基本的一级 Axes:在Figure上创建子图的容器(如果Figure中仅含一子图,则该容器可省略) Axis:用于处理子图上和坐标轴和网格相关的元素 T ...
- editorial 专栏
社论 22.10.1 solution for pl_er 密码是我的名字的拼音 全小写无空格 社论 22.10.2 solution for Simu. 密码是联考密码 社论 22.10.4 sol ...
- Linux相关命令及软件安装教程
@font-face { font-family: "Times New Roman" } @font-face { font-family: "宋体" } @ ...
- 【离线数仓】Day02-用户行为数据仓库:分层介绍、环境搭建(hive、tez)、LZO压缩、建表查询导入加索引、编写脚本
一.数仓分层概念 1.为什么要分层 ODS:原始数据层 DWD层:明细数据层 DWS:服务数据层 ADS:数据应用层 2.数仓分层 3.数据集市与数据仓库概念 4.数仓命名规范 ODS层命名为odsD ...
- node版本管理工具fnm踩坑
我建议是直接不要用fnm,还是老老实实用nvm吧 fnm下下来电脑防火墙会报毒(用github上推荐的cargo install fnm方式下载,并非第三方安装) Trojan.Generic.HgE ...
- 《HTTP权威指南》– 3.HTTP方法和状态码
常见HTTP方法: 常用HTTP方法 描述 是否包含主体 GET 从服务器获取一份文档 否 HEAD 只从服务器获取文档的首部 否 POST 向服务器发送需要处理的数据 是 PUT 将请求的主体部分存 ...
- Vue DevUI v1.4 版本发布:从体验、效率、质量三个方面做了全方位的优化🎉
2022年9月1日,我们正式宣布 Vue DevUI 组件库发布 v1.0 版本. Vue DevUI 1.0 正式发布 经过100多天的持续迭代,我们正式发布 v1.4.0 版本,共新增: 11位贡 ...
- idea 函数名灰色
idea被引用的方法名突然全部灰掉了 idea被引用的方法名突然全部灰掉了[已解决]_weixin_42554373的博客-CSDN博客_idea方法名灰色
- Web初级——模块和Bom
模块导入 导出声明 定义时声明 在定义声明函数.类时不用加分号 // 导出数组 export let months = ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep' ...
- ionic+vue+capacitor系列笔记--01项目初始化
Ionic 是什么? Ionic 是一款接近原生的 Html5 移动 App 开发框架,只需要你会 HTML.CSS 和 JavaScript 就可以开发移动 App应用,使用最基础的 Web 技术创 ...