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

删除节点,找到节点分情况讨论

  1. 节点是叶子节点,直接删除
  2. 节点是分支节点,找左子树的最大值或右子树的最小值节点的pre节点,左树最大值节点可能有左子树,右树最小值节点可能有右子树,pre节点还可能是当前节点
    1. 有左子树有右子树 
    2. 有左子树无右子树
    3. 无左子树有右子树
  3. 删除节点要知道这个节点的父节点 每次递归前先令pre = 当前节点
  4. 还要清楚待删节点是父节点的左节点还是右节点,设置参数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 上看到一个思路

如果目标节点大于当前节点值,则去右子树中删除;
如果目标节点小于当前节点值,则去左子树中删除;
如果目标节点就是当前节点,分为以下三种情况:
其无左子:其右子顶替其位置,删除了该节点;
其无右子:其左子顶替其位置,删除了该节点;
其左右子节点都有:其左子树转移到其右子树的最左节点的左子树上,然后右子树顶替其位置,由此删除了该节点。

总结

  1. 头脑中要有一棵树,树形象上的特点,遍历序列上的特点
  2. 一定要先想清楚代码逻辑、循环逻辑、递归逻辑再继续
  3. 我的做题思维通常都是用代码模拟人脑

常用变量名增量更新

size、val、ans、cnt、cur、pre、next、left、right、index、gap、tar、res、src、len、start、end、flag、ch

代码随想录算法训练营day22 | leetcode 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点的更多相关文章

  1. [程序员代码面试指南]二叉树问题-在二叉树中找到两个节点的最近公共祖先、[LeetCode]235. 二叉搜索树的最近公共祖先(BST)(非递归)

    题目 题解 法一: 按照递归的思维去想: 递归终止条件 递归 返回值 1 如果p.q都不在root为根节点的子树中,返回null 2 如果p.q其中之一在root为根节点的子树中,返回该节点 3 如果 ...

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

    235. 二叉搜索树的最近公共祖先 235. Lowest Common Ancestor of a Binary Search Tree 题目描述 给定一个二叉搜索树,找到该树中两个指定节点的最近公 ...

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

    235. 二叉搜索树的最近公共祖先 题目描述 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先 ...

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

    Leetcode:235. 二叉搜索树的最近公共祖先 Leetcode:235. 二叉搜索树的最近公共祖先 Talk is cheap . Show me the code . /** * Defin ...

  5. Java实现 LeetCode 235 二叉搜索树的最近公共祖先

    235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个 ...

  6. 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

    剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q ...

  7. 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 + 二叉排序树 + 最近公共祖先

    剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 Offer_68_1 题目描述 方法一:迭代法 由于该题的二叉树属于排序二叉树,所以相对较简单. 只需要判断两个结点是否在根节点的左右子树中 ...

  8. [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 ...

  9. leetcode 235. 二叉搜索树的最近公共祖先(c++)

    给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x ...

  10. 利用Tarjan算法解决(LCA)二叉搜索树的最近公共祖先问题——数据结构

    相关知识:(来自百度百科)  LCA(Least Common Ancestors) 即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. 例如: 1和7的最近公共祖先为5: 1和5的 ...

随机推荐

  1. flutter系列之:flutter中的变形金刚Transform

    目录 简介 Transform简介 Transform的使用 总结 简介 虽然我们在开发APP的过程中是以功能为主,但是有时候为了美观或者其他的特殊的需求,需要对组件进行一些变换.在Flutter中这 ...

  2. 常用函数/异常处理/for循环本质

    常用内置函数 1,map() - 映射 格式: map(函数,可遍历对象) 指将遍历的元素挨个取出来做函数的行参传参,得到的返回值全部放回map工厂中,map工厂可以被转换成列表查看到 每一个被函数处 ...

  3. 多种方法实现单例模式 pickle模块

    目录 单例模式 类方法@classmethod实现 元类实现 模块实现 装饰器实现 双下call.反射实现 pickle序列化模块 单例模式 比如系统调用打印机,不管你要打印几次,都是调用同一个打印机 ...

  4. 成功解决pycharm 的setting中的Error occurred when installing package 'Keras'

    成功解决pycharm 的setting中的Error occurred when installing package 'Keras' 刚刚开始学习python在安装package上碰了不上壁. M ...

  5. BFS广度优先搜索例题分析

    洛谷P1162 填涂颜色 题目描述 由数字 \(0\) 组成的方阵中,有一任意形状闭合圈,闭合圈由数字 \(1\) 构成,围圈时只走上下左右 \(4\) 个方向.现要求把闭合圈内的所有空间都填写成 \ ...

  6. Sql Server中order by对varchar类型排序结果不对

    1.问题描述 我写一个sql想要把查询结果根据LineNumber升序进行排序,即1.0,1.1,1.2,...1.3.2....2.0,......10.0,......15.2,......这样子 ...

  7. [OpenCV实战]3 透明斗篷

    目录 1寻找和存储背景帧 2红色区域检测 3提取红色区域 4背景帧红布区域替换当前帧红布区域. 5工程代码 参考 弄出哈利波特电影里一样效果的透明斗篷.也就是一个视频里,将红布弄成透明.类似下面的效果 ...

  8. 避免用Apache Beanutils进行属性的copy。why?让我们一起一探究竟

    在实际的项目开发中,对象间赋值普遍存在,随着双十一.秒杀等电商过程愈加复杂,数据量也在不断攀升,效率问题,浮出水面. 问:如果是你来写对象间赋值的代码,你会怎么做? 答:想都不用想,直接代码走起来,g ...

  9. VUEX 使用学习三 : mutations

    转载请注明出处: 在 Vuex 中 store 数据改变的唯一方法就是提交 mutations.mutations里面装着一些改变数据方法的集合,这是Vuex 设计很重要的一点,就是把处理数据逻辑方法 ...

  10. 从0到1手把手实现vite

    什么是Vite? 法语:轻量化,快速 基于VUE3 非 打包开发服务器,请注意,它是个开发服务器哇!! 快速开发,按需编译,不再等待整个应用编译完成 基于原生模块系统ESModule实现 说白了,就是 ...