【算法训练-二叉树 五】【最近公共祖先】二叉树的最近公共祖先、二叉搜索树的最近公共祖先

简介: 【算法训练-二叉树 五】【最近公共祖先】二叉树的最近公共祖先、二叉搜索树的最近公共祖先

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【二叉树的节点查找】,使用【二叉树】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为:目标公司+最近一年+出现频率排序,由高到低的去牛客TOP101去找,只有两个地方都出现过才做这道题(CodeTop本身汇聚了LeetCode的来源),确保刷的题都是高频要面试考的题。

明确目标题后,附上题目链接,后期可以依据解题思路反复快速练习,题目按照题干的基本数据结构分类,且每个分类的第一篇必定是对基础数据结构的介绍

二叉搜索树的最近公共祖先【MID】

同上一题的解法,再练习一遍

题干

解题思路

根据以上定义,若 root 是 p,q的 最近公共祖先 ,则只可能为以下情况之一:

  1. p 和 q 在 root 的子树中,且分列 root 的 异侧(即分别在左、右子树中);
  2. p=root ,且 q 在 roo的左或右子树中
  3. q=root,且 p 在 root的左或右子树中

  1. 终止条件:当越过叶节点,则直接返回 null;当 root 等于 p,q,则直接返回 root;
  2. 递推工作: 开启递归左子节点,返回值记为 left;开启递归右子节点,返回值记为 right;
  3. 返回值: 根据 left和 right,可展开为四种情况;
  • 当 left 和 righ同时为空 :说明一直遍历到叶节点, root 的左 / 右子树中都不包含 p,q ,返回 null;
  • 当 left和 right 同时不为空 :说明 pq 分列在 roo的 异侧 (分别在 左 / 右子树),因此 root为最近公共祖先,返回 root
  • 当 left为空 ,right不为空 :pq 都不在 root 的左子树中,直接返回 right。具体可分为两种情况:pq 其中一个在 root 的 右子树 中,此时 right指向 p(假设为 p );pq 两节点都在 root的 右子树 中,此时的 right指向 最近公共祖先节点 ;
  • 当 left不为空 , right为空 :与情况 3. 同理

代码实现

给出代码实现基本档案

基本数据结构二叉树

辅助数据结构

算法递归、DFS

技巧

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

public TreeNode lowestCommonAncestor (TreeNode root, TreeNode p, TreeNode q) {
        if (root == null) {
            return null;
        }
        return dfsFindRoot(root, p, q);
    }
    private TreeNode dfsFindRoot(TreeNode node, TreeNode p, TreeNode q) {
        // 1 递归终止条件:越过叶子节点没找到;root为p或root为q
        if (node == null || node == p || node == q) {
            return node;
        }
        // 2 本级任务:分别在左右子树中寻找节点
        TreeNode left = dfsFindRoot(node.left, p, q);
        TreeNode right = dfsFindRoot(node.right, p, q);
        // 3 本级任务:分别在左右子树中寻找节点
        if (left != null && right != null) {
            //如果两个节点分别存在于左右子树,则当前节点即是最近公共祖先
            return node;
        }
        // 如果两个节点在root的同侧,则返回的节点即为公共节点
        if (right == null && left != null) {
            return left;
        }
        if (right != null && left == null) {
            return right;
        }
        // 如果两个节点左右都没有找到,则返回null
        return null;
    }

复杂度分析

时间复杂度:O(n),其中n为二叉树的节点数,遍历整棵二叉树

空间复杂度:O(n),最坏情况下,二叉树化为链表,递归栈深度最大为n

二叉树的最近公共祖先【MID】

最近公共祖先(Lowest Common Ancestor, LCA)是指在一个二叉树中,两个节点p和q的最低公共祖先节点,即深度最深且同时是p和q的祖先的节点,同时节点本身也可以为其最近公共祖先

题干

解题思路

根据以上定义,若 root 是 p,q的 最近公共祖先 ,则只可能为以下情况之一:

  1. p 和 q 在 root 的子树中,且分列 root 的 异侧(即分别在左、右子树中);
  2. p=root ,且 q 在 roo的左或右子树中
  3. q=root,且 p 在 root的左或右子树中

  1. 终止条件:当越过叶节点,则直接返回 null;当 root 等于 p,q,则直接返回 root;
  2. 递推工作: 开启递归左子节点,返回值记为 left;开启递归右子节点,返回值记为 right;
  3. 返回值: 根据 left和 right,可展开为四种情况;
  • 当 left 和 righ同时为空 :说明一直遍历到叶节点, root 的左 / 右子树中都不包含 p,q ,返回 null;
  • 当 left和 right 同时不为空 :说明 pq 分列在 roo的 异侧 (分别在 左 / 右子树),因此 root为最近公共祖先,返回 root
  • 当 left为空 ,right不为空 :pq 都不在 root 的左子树中,直接返回 right。具体可分为两种情况:pq 其中一个在 root 的 右子树 中,此时 right指向 p(假设为 p );pq 两节点都在 root的 右子树 中,此时的 right指向 最近公共祖先节点 ;
  • 当 left不为空 , right为空 :与情况 3. 同理

代码实现

给出代码实现基本档案

基本数据结构二叉树

辅助数据结构

算法递归、DFS

技巧

其中数据结构、算法和技巧分别来自:

  • 10 个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie 树
  • 10 个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法
  • 技巧:双指针、滑动窗口、中心扩散

当然包括但不限于以上

import java.util.*;
/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param root TreeNode类
     * @param p int整型
     * @param q int整型
     * @return int整型
     */
    public int lowestCommonAncestor (TreeNode root, int p, int q) {
        if (root == null) {
            return -1;
        }
        return dfsCheck(root, p, q);
    }
    private int dfsCheck(TreeNode node, int p, int q) {
        // 1 递归终止条件,找到了则返回值,超过叶子节点没找到则返回-1
        if (node == null) {
            return -1;
        }
        if ( node.val == p || node.val == q) {
            return node.val;
        }
        // 2 获取左右子树的查找结果
        int rightVal = dfsCheck(node.right, p, q);
        int leftVal = dfsCheck(node.left, p, q);
        // 3 依据查找结果判断取值
        if (rightVal != -1 && leftVal != -1) {
            // p、q分别在左右子树,且都不作为公共祖先
            return node.val;
        } else if (rightVal == -1) {
            // 右子树没有找到,左子树找到了,则返回左子树找到的最近公共祖先
            return leftVal;
        } else if (leftVal == -1) {
            // 左子树没有找到,右子树找到了,则返回右子树找到的最近公共祖先
            return rightVal;
        } else {
            // 两边都没找到,返回-1;
            return -1;
        }
    }
}

复杂度分析

时间复杂度:O(n),其中n为二叉树的节点数,遍历整棵二叉树

空间复杂度:O(n),最坏情况下,二叉树化为链表,递归栈深度最大为n

拓展知识:二叉树的最近公共祖先

最近公共祖先(Lowest Common Ancestor, LCA)是指在一个二叉树中,两个节点p和q的最低公共祖先节点,即深度最深且同时是p和q的祖先的节点。以下是一种基于递归的实现思路,并提供Java的实现代码:

定义

假设有一个二叉树,每个节点包含如下信息:

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

实现思路

  1. 从根节点开始遍历二叉树。
  2. 对于当前节点,递归地查找其左子树和右子树,看看是否能找到节点p和节点q。
  3. 如果左子树中找到了节点p或节点q,或者右子树中找到了节点p或节点q,那么当前节点就是它们的最近公共祖先。
  4. 如果左子树和右子树都找到了最近公共祖先,那么当前节点就是它们的最近公共祖先。
  5. 最后,返回最近公共祖先。

Java实现代码

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    // Base case: 如果当前节点为空或者等于p或q中的任意一个,直接返回当前节点
    if (root == null || root == p || root == q) {
        return root;
    }
    // 递归查找左子树和右子树
    TreeNode leftLCA = lowestCommonAncestor(root.left, p, q);
    TreeNode rightLCA = lowestCommonAncestor(root.right, p, q);
    // 如果左子树和右子树都找到了最近公共祖先,那么当前节点就是最近公共祖先
    if (leftLCA != null && rightLCA != null) {
        return root;
    }
    // 如果只在一侧找到了最近公共祖先,返回那一侧找到的结果
    return (leftLCA != null) ? leftLCA : rightLCA;
}

这段代码会在二叉树中查找节点p和q的最近公共祖先,并返回该节点。如果一个节点是另一个节点的祖先,那么它自己也可以是自己的祖先,因此在递归中会检查当前节点是否等于p或q中的任意一个,如果是就返回当前节点。否则,递归地查找左子树和右子树,并根据左右子树的结果确定最近公共祖先。

相关文章
|
8月前
|
机器学习/深度学习 存储 算法
解锁文件共享软件背后基于 Python 的二叉搜索树算法密码
文件共享软件在数字化时代扮演着连接全球用户、促进知识与数据交流的重要角色。二叉搜索树作为一种高效的数据结构,通过有序存储和快速检索文件,极大提升了文件共享平台的性能。它依据文件名或时间戳等关键属性排序,支持高效插入、删除和查找操作,显著优化用户体验。本文还展示了用Python实现的简单二叉搜索树代码,帮助理解其工作原理,并展望了该算法在分布式计算和机器学习领域的未来应用前景。
|
5月前
|
存储 监控 算法
公司内部网络监控中的二叉搜索树算法:基于 Node.js 的实时设备状态管理
在数字化办公生态系统中,公司内部网络监控已成为企业信息安全管理体系的核心构成要素。随着局域网内终端设备数量呈指数级增长,实现设备状态的实时追踪与异常节点的快速定位,已成为亟待解决的关键技术难题。传统线性数据结构在处理动态更新的设备信息时,存在检索效率低下的固有缺陷;而树形数据结构因其天然的分层特性与高效的检索机制,逐渐成为网络监控领域的研究热点。本文以二叉搜索树(Binary Search Tree, BST)作为研究对象,系统探讨其在公司内部网络监控场景中的应用机制,并基于 Node.js 平台构建一套具备实时更新与快速查询功能的设备状态管理算法框架。
138 3
|
7月前
|
存储 算法 Java
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
189 10
 算法系列之数据结构-二叉树
|
7月前
|
算法 Java
算法系列之数据结构-二叉搜索树
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
194 22
|
7月前
|
存储 监控 算法
基于 PHP 二叉搜索树算法的内网行为管理机制探究
在当今数字化网络环境中,内网行为管理对于企业网络安全及高效运营具有至关重要的意义。它涵盖对企业内部网络中各类行为的监测、分析与管控。在内网行为管理技术体系里,算法与数据结构扮演着核心角色。本文将深入探究 PHP 语言中的二叉搜索树算法于内网行为管理中的应用。
69 4
|
8月前
|
存储 算法 Java
解锁“分享文件”高效密码:探秘 Java 二叉搜索树算法
在信息爆炸的时代,文件分享至关重要。二叉搜索树(BST)以其高效的查找性能,为文件分享优化提供了新路径。本文聚焦Java环境下BST的应用,介绍其基础结构、实现示例及进阶优化。BST通过有序节点快速定位文件,结合自平衡树、多线程和权限管理,大幅提升文件分享效率与安全性。代码示例展示了文件插入与查找的基本操作,适用于大规模并发场景,确保分享过程流畅高效。掌握BST算法,助力文件分享创新发展。
|
8月前
|
监控 算法 安全
关于公司电脑桌面监控中 PHP 二叉搜索树算法的深度剖析
在现代企业管理中,公司电脑桌面监控系统通过二叉搜索树(BST)算法保障信息安全和提高效率。本文探讨PHP中的BST在监控场景的应用,包括节点定义、插入与查找操作,并展示如何管理时间戳数据,以快速查询特定时间段内的操作记录。BST的高效性使其成为处理复杂监控数据的理想选择。
65 2
|
9月前
|
存储 算法 安全
U 盘管控情境下 Python 二叉搜索树算法的深度剖析与探究
在信息技术高度发达的今天,数据安全至关重要。U盘作为常用的数据存储与传输工具,其管控尤为关键。本文探讨Python中的二叉搜索树算法在U盘管控中的应用,通过高效管理授权U盘信息,防止数据泄露,保障信息安全。二叉搜索树具有快速插入和查找的优势,适用于大量授权U盘的管理。尽管存在一些局限性,如树结构退化问题,但通过优化和改进,如采用自平衡树,可以有效提升U盘管控系统的性能和安全性。
96 3
|
9月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
261 3
|
10月前
|
存储 算法 Python
文件管理系统中基于 Python 语言的二叉树查找算法探秘
在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
151 5

热门文章

最新文章