代码随想录Day18 LeetCode235 二叉搜索树的公共祖先 T701二叉搜索树中的插入操作 T140 删除二叉搜索树中的公共节点

简介: 代码随想录Day18 LeetCode235 二叉搜索树的公共祖先 T701二叉搜索树中的插入操作 T140 删除二叉搜索树中的公共节点

LeetCode T235 二叉搜索树的公共祖先

题目链接235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

题目思路

此题不涉及遍历顺序.

关于二叉搜索树的定义,这里我就不过多赘述了,前面几篇都说清楚了,根节点比左子树元素都大,比右子树元素都小,这道题我们就可以知道,两个节点的最近公共祖先一定满足夹在两个节点的中间这个条件.

那么,夹在两个节点之间的一定是最近的公共祖先吗?

答案是肯定的,我们不妨这样想,如果我们的节点这个时候再向左遍历,我们就会丢失右子树包含的那个节点,左子树同理.思路理顺了我们就来书写代码吧.

递归三部曲

1.函数参数和返回值

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)

2.终止条件

如果遇到空节点,直接返回空节点即可

if(root == null)
        {
            return null;
        }

3.一次递归逻辑

if(root.val>q.val && root.val>p.val)
        {
            TreeNode left = lowestCommonAncestor(root.left,p,q);
            if(left != null)
            {
                return left;
            }
        }
        if(root.val<q.val && root.val<p.val)
        {
            TreeNode right = lowestCommonAncestor(root.right,p,q);
            if(right != null)
            {
                return right;
            }
        }
        return root;

其实我么也发现了,无论遇不遇到空节点都可以直接返回,那么我们的代码又可以进一步的简化.

题目代码

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null)
        {
            return null;
        }
        if(root.val>q.val && root.val>p.val)
        {
            TreeNode left = lowestCommonAncestor(root.left,p,q);
            if(left != null)
            {
                return left;
            }
        }
        if(root.val<q.val && root.val<p.val)
        {
            TreeNode right = lowestCommonAncestor(root.right,p,q);
            if(right != null)
            {
                return right;
            }
        }
        return root;
    }
}
//上述代码的简化版
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;
    }
}
//迭代法
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        while(true)
        {
            if(root.val>q.val && root.val>p.val)
            {
                root = root.left;
            }
            else if(root.val<q.val && root.val<p.val)
            {
                root = root.right;
            }
            else
            {
                break;
            }
        }
        return root;
    }
}

LeetCode T701 二叉搜索树中的插入操作

题目链接701. 二叉搜索树中的插入操作 - 力扣(LeetCode)

题目思路

这里我们看到这道题可以改变二叉搜索树的形状,可以返回任意有效的结果,我们就有点慌,其实这里我们所有节点的插入都可以在叶子节点完成,无论插入什么大小的节点我们都可以插入在叶子节点来解决问题.那么有了这个思路题目就变得简单了,我们只需要找到对应的叶子节点,创建一个新节点再连接即可.下面我们看看代码怎么写.

函数参数以及返回值

这里就用LeetCode本身提供的函数即可

2.终止条件

遇见空节点就说明我们找到了,直接创建新节点,向上返回即可

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

3.单次递归

如果在左边插入,就用左子树来接收这个节点,反之用右子树来接收

if(val<root.val)
        {
            root.left = insertIntoBST(root.left,val);
        }
        if(val>root.val)
        {
            root.right = insertIntoBST(root.right,val);
        }
        return root;

题目代码

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null)
        {
            TreeNode node = new TreeNode(val);
            return node;
        }
        if(val<root.val)
        {
            root.left = insertIntoBST(root.left,val);
        }
        if(val>root.val)
        {
            root.right = insertIntoBST(root.right,val);
        }
        return root;
    }
}

LeetCode T140 删除二叉搜索树的节点

题目链接450. 删除二叉搜索树中的节点 - 力扣(LeetCode)

题目思路

这里我们先考虑五种可能的情况

1.找不到这个key对应的节点

2.能找到

2.1这个节点是叶子结点

直接返回空即可

2.2这个节点的左孩子为空,右孩子不为空

返回右孩子

2.3这个节点的左孩子不为空,右孩子为空

返回左孩子

2.4这个节点左右孩子都不为空

这个的处理较为复杂,我们举个例子说明

假设我们要删除7节点,我们就得调整二叉树的结构

假设我们保留右子树(保留左子树也可以,方法一样)

我们找到右子树中的最小值(右子树中的左子树的最小值),将原左子树接在这个节点下面即可

递归逻辑

1.确定递归函数以及返回值

使用函数本身即可

2.确定终止条件

由于这次的终止条件是找到节点的过程,所以较为复杂

if(root == null)
        {
            return null;
        }
        if(root.val == key)
        {
            if(root.left == null && root.right == null)
            {
                return  null;
            }
            else if(root.left != null && root.right == null)
            {
                return root.left;
            }
            else if(root.right != null && root.left == null)
            {
                return root.right;
            }
            else {
            TreeNode cur = root.right;
            while (cur.left != null) {
             cur = cur.left;
            }
            cur.left = root.left;
            root = root.right;
            return root;
      }
}

3.确定一次递归逻辑

if(root.val<key)
        {
            root.right =  deleteNode(root.right,key);
        }
        if(key<root.val)
        {
            root.left =  deleteNode(root.left,key);
        }
        return root;

题目代码

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if(root == null)
        {
            return null;
        }
        if(root.val == key)
        {
            if(root.left == null && root.right == null)
            {
                return  null;
            }
            else if(root.left != null && root.right == null)
            {
                return root.left;
            }
            else if(root.right != null && root.left == null)
            {
                return root.right;
            }
            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.right =  deleteNode(root.right,key);
        }
        if(key<root.val)
        {
            root.left =  deleteNode(root.left,key);
        }
        return root;
    }
}
相关文章
|
3月前
【LeetCode 45】701.二叉搜索树中的插入操作
【LeetCode 45】701.二叉搜索树中的插入操作
16 1
|
3月前
【LeetCode 44】235.二叉搜索树的最近公共祖先
【LeetCode 44】235.二叉搜索树的最近公共祖先
20 1
|
3月前
【LeetCode 48】108.将有序数组转换为二叉搜索树
【LeetCode 48】108.将有序数组转换为二叉搜索树
45 0
|
3月前
【LeetCode 47】669.修剪二叉搜索树
【LeetCode 47】669.修剪二叉搜索树
13 0
|
3月前
【LeetCode 46】450.删除二叉搜索树的节点
【LeetCode 46】450.删除二叉搜索树的节点
22 0
|
4月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
64 6
|
5月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
130 2
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
56 1
|
4月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口