持续创作,加速生长!这是我参加「日新方案 10 月更文应战」的第3天,点击检查活动详情

二叉树的最近公共先人

标题

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

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

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]

二叉树总结之最近公共祖先

示例1:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出: 3
解释: 节点 5 和节点 1 的最近公共先人是节点 3

示例2:

输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
输出: 5
解释: 节点 5 和节点 4 的最近公共先人是节点 5。因为依据定义最近公共先人节点可以为节点自身。

解题思路

假设 root 是 p, q 的最近公共先人,那么就可以有以下三种状况:

  1. p 和 q 在 root 的子树中,且分列 root 的左、右子树中;
  2. p = root,且 q 在 root 的左或右子树中;
  3. q = root,且 p 在 root 的左或右子树中;

在这里,咱们运用二叉树先序遍历的方式来对此二叉树进行查找;当遇到节点 p 或许 q 的时分回来。自底向上回溯,当节点 p, q 在节点 root 的异侧时,节点 root 即为最近公共先人,则向上回来 root 。

递归函数解析:

  1. 终止条件:当遇到根节点时,则直接回来 null; 当 root 等于 p 或许 q 的时分,回来 root。
  2. 单层递归逻辑:敞开递归左子节点,回来值记为 left; 敞开递归右子节点,回来值记为 right。
  3. 回来值:当 left 和 right 都为 null 时,阐明没有找到 p 和 q, 回来 null;当 left 和 right 都不为空时,则 p 和 q 别离坐落 root 俩侧,所以 root 为最近的先人节点,回来 root; 当 left 为空,right 不为空,阐明 p,q 都不在 root 的左子树中,则直接回来 right, 反之,回来 left。

代码完成

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == p || root == q){
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if(left == null && right == null) return null;
        if (left == null) {
            return right;
        }
        if (right == null) {
            return left;
        }
        return root;
    }
}

复杂度剖析

  • 时刻复杂度:O(N),其间 NN 是二叉树的节点数。二叉树的一切节点有且只会被拜访一次,因而时刻复杂度为 O(N)。

  • 空间复杂度:O(N) ,其间 N 是二叉树的节点数。递归调用的栈深度取决于二叉树的高度,二叉树最坏状况下为一条链,此时高度为 N,因而空间复杂度为 O(N)。

二叉查找树的最近公共先人

Hello, 咱们好,今天是8月更文的第 4 天,今天要和咱们分享的关于二叉树的算法题是:给定一个二叉查找树,找到该树中俩个指定节点的最近的公共先人。

标题

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

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

例如:给定如下二叉查找树: root = [6,2,8,0,4,7,9,null,null,3,5]

二叉树总结之最近公共祖先

示例1:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6 
解释: 节点 2 和节点 8 的最近公共先人是 6

示例2:

输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共先人是 2, 因为依据定义最近公共先人节点可以为节点自身。

思路剖析

注意到标题中给出的是一棵二叉查找树,而二叉查找树的特色就是 左子树的一切节点都小于当时节点,右子树的一切节点都大于当时节点,并且每棵子树都具有上述特色,因而咱们可以快速地找出树中的某个节点以及从根节点到该节点的路径。

所以这题就好办了,咱们从根节点开端遍历:

  1. 假如当时节点的值大于 p 和 q 的值,阐明 p 和 q 应该在当时节点的左子树,因而将当时节点移动到它的左子节点;

  2. 假如当时节点的值小于 p 和 q 的值,阐明 p 和 q 应该在当时节点的右子树,因而将当时节点移动到它的右子节点;

  3. 假如当时节点的值不满意上述两条要求,那么阐明当时节点就是分岔点。此时,p 和 q 要么在当时节点的不同的子树中,要么其间一个就是当时节点。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
/*
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 第一种状况,当时节点的值小于给定的值,则阐明满意条件的在右边
        if(root.val < p.val && root.val < q.val){
            return lowestCommonAncestor(root.right, p, q);
        }
        // 第二种状况,当时节点的值大于给定的值,则阐明满意条件的在左边
        if(root.val>p.val&&root.val>q.val){
            return lowestCommonAncestor(root.left, p, q);
        }
        // 第三种状况,p,q不在同一子树,只能是p,q别离在一左一右,或许,p,q其间一个是根节点,都回来root
        return root;
    }
}

复杂度剖析

  1. 时刻复杂度:O(n),其间 n 是给定的二叉查找树中的节点个数。

  2. 空间复杂度:O(1)。

我是杰少,假如您觉的我写的不错,那请给我 点赞+评论+收藏 后再走哦!

往期文章:

  • 运用 Google Breakpad 来助力解决程序崩溃
  • UE4 多人游戏服务器探索
  • 运用虚幻引擎主动化工具完成主动化部署
  • 怎么在 UE4 中制造一扇主动敞开的大门
  • 怎么在 UE4 中用代码去控制人物移动
  • 怎么给 UE4 场景添加游戏人物
  • UE4:Android 平台开发实践指南
  • UE4 开发避坑指南(持续更新)
  • 新年开工啦,放个小烟花庆祝一下
  • 聊聊与苹果审核员的爱恨情仇(下)
  • 聊聊与苹果审核员的爱恨情仇(上)
  • 一名普通工具人的 2021 | 2021年终总结
  • 二叉树刷题总结:二叉查找树的属性
  • 二叉树总结:二叉树的属性
  • 二叉树总结:二叉树的修改与结构
  • StoreKit2 有这么香?嗯,我试过了,真香
  • 看完这篇文章,再也不怕面试官问我怎么结构二叉树啦!
  • 那帮做游戏的又想让咱们氪金,太坏了!
  • 手把手带你撸一个网易云音乐主页 | 适配篇
  • 手把手带你撸一个网易云音乐主页(三)
  • 手把手带你撸一个网易云音乐主页(二)
  • 手把手带你撸一个网易云音乐主页(一)
  • 代码要写注释吗?写你就输了
  • Codable发布这么久我就不学,摸鱼爽歪歪,哎~就是玩儿
  • iOS 高雅的处理网络数据,你真的会吗?不如看看这篇
  • UICollectionView 自定义布局!看这篇就够了

请你喝杯 ☕️ 点赞 + 重视哦~

  1. 阅读完记住给我点个赞哦,有 有动力
  2. 重视大众号— HelloWorld杰少,第一时刻推送新姿态

最后,创作不易,假如对咱们有所协助,希望咱们点赞支持,有什么问题也可以在评论区里评论~**