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. JavaScript入门③-函数(2)原理{深入}执行上下文

    00.头痛的JS闭包.词法作用域? 被JavaScript的闭包.上下文.嵌套函数.this搞得很头痛,这语言设计的,感觉比较混乱,先勉强理解总结一下. 为什么有闭包这么个东西?闭包包的是什么? 什么 ...

  2. aiohttp、asyncio使用协程增加爬虫效率

    import aiohttp import asyncio import time async def get_requests(url): async with aiohttp.ClientSess ...

  3. 持续发烧,聊聊Dart语言的静态编译,能挑战Go不?

    前言 前两天写了几篇文章,谈了谈Dart做后端开发的优势,比如: <Dart开发服务端,我是不是发烧(骚)了?> <持续发烧,试试Dart语言的异步操作,效率提升500%> & ...

  4. nuxt.js中登录、注册(密码登录和手机验证码登录)

    <!-- 登录弹框 --> <div class="mask" v-show="flag"> <div class="m ...

  5. AcWing340通信道路/ USACO2008 Telephone Line S

    AcWing题目 洛谷题目 解题思路 首先可以得到一个很容易得到的贪心策略,将一条路径上最贵的(边权最大)的\(K\)条边删去,那么我们剩下的路径中最贵(边权最大)的路就是原本这条路径上帝\(K + ...

  6. linux系统中安装虚拟机

    在linux系统中,利用图形化界面安装虚拟机.首先启动 virt-manager,当然没有安装 virt-manager需要先安装好. 1 $ apt-get install virt-manager ...

  7. 学习ASP.NET Core Blazor编程系列十九——文件上传(下)

    学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...

  8. [OpenCV实战]18 Opencv中的单应性矩阵Homography

    目录 1 介绍 1.1 什么是Homography 1.2 使用Homography进行图像对齐 1.3 Homography的应用-全景拼接 2 Homography的计算 3 总结 4 参考 &l ...

  9. kafka详解(01) - 概述

    kafka详解(01) - 概述 定义:Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域. 消息队列 MQ传统应用场景之异步处理 使用消 ...

  10. [cocos2d-x]从源码角度思考convertToWorldSpace()与convertToWorldSpaceAR()坐标系的转换

    convertToWorldSpace() 话不多说,先上源码,之后再慢慢讲解: (5和6图截图的时候重复了,这里就不弄出来了) 只要通过图1到图8中我写的注释进行分析(不懂的地方可以自己去翻一下co ...