news 2026/6/30 2:24:57

剑指offer-81、⼆叉搜索树的最近公共祖先 _

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
剑指offer-81、⼆叉搜索树的最近公共祖先 _

题⽬描述

给定⼀个⼆叉搜索树, 找到该树中两个指定节点的最近公共祖先。

  1. 对于该题的最近的公共祖先定义:对于有根树T的两个结点p 、q ,最近公共祖先LCA(T,p,q)表示⼀个结点x ,满⾜x 是p 和q 的祖先且x 的深度尽可能⼤。在这⾥,⼀个节点也可以是它⾃⼰的祖先.
  2. ⼆叉搜索树是若它的左⼦树不空,则左⼦树上所有结点的值均⼩于它的根结点的值; 若它的右⼦树不空,则右⼦树上所有结点的值均⼤于它的根结点的值
  3. 所有节点的值都是唯⼀的。
  4. p 、q 为不同节点且均存在于给定的⼆叉搜索树中。

如果给定以下搜索⼆叉树: {7,1,12,0,4,11,14,#,#,3,5} ,如下图:

示例1
输⼊: {7,1,12,0,4,11,14,#,#,3,5},1,12
输出: 7
说明:节点1 和 节点12的最近公共祖先是7

示例2:
输⼊: {7,1,12,0,4,11,14,#,#,3,5},12,11
输出: 12
说明:因为⼀个节点也可以是它⾃⼰的祖先.所以输出12

思路及解答

迭代遍历

二叉搜索树(BST)的特性,通过迭代查找公共祖先,根据节点值大小关系,决定向左子树或右子树查找

java

public class Solution { public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { if (root == null) return null; TreeNode current = root; while (current != null) { // 如果p和q的值都小于当前节点,LCA在左子树 if (p.val < current.val && q.val < current.val) { current = current.left; } // 如果p和q的值都大于当前节点,LCA在右子树 else if (p.val > current.val && q.val > current.val) { current = current.right; } // 否则当前节点就是LCA else { return current; } } return null; // 未找到 } }
  • 时间复杂度:O(h),h为树高,平均O(log n),最坏O(n)
  • 空间复杂度:O(1),只使用常数空间

递归遍历

递归判断节点值关系,决定向左或右递归查找

题⽬已经保证了,两个节点 p , q 都在树上,我们取出根节点 7 ,假设⼩于 7 ,则在左⼦树,如果⼤于7 ,则在右⼦树。

需要查找的两个节点,但凡有⼀个等于根节点,它们的⽗节点就是根节点,因为⼀个节点的⽗节点可以是⾃身(题⽬有说明)。

如果⼀个⼤于根节点,⼀个⼩于更节点,其最近公共祖先也是根节点。如果两个都⼤于,或者两个都⼩于,怎么办?

当然是递归,如果两个都⼩于,那么就取当前的左⼦树进⾏递归,直到符合要求。⽐如查找,3 和 5,由于 3 和 5 都⼩于 7,那么取左⼦树 1 下⾯的进⾏递归:

java

class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } public class Solution68 { public int lowestCommonAncestor(TreeNode root, int p, int q) { TreeNode result = commonAncestor(root, p, q); return result == null ? -1 : result.val; } public TreeNode commonAncestor(TreeNode root, int p, int q) { // 等于空 if (root == null) { return null; } if (root.val == p || root.val == q) { // 有⼀个值等于根节点 return root; } // 在左⼦树 if (p < root.val && q < root.val) { return commonAncestor(root.left, p, q); } else if (p > root.val && q > root.val) { // 两个都在右⼦树 return commonAncestor(root.right, p, q); } else { return root; } } }
  • 时间复杂度:O(h),递归深度为树高
  • 空间复杂度:O(h),递归调用栈空间

通用二叉树

假设这道题条件改⼀下,如果不是⼆叉搜索树,怎么办?

如果不是⼆叉搜索树,那么我们不能直接判断出它在左⼦树,还是在右⼦树。不如暴⼒点,先在左⼦树中找,如果右⼦树没找到,说明都在左⼦树,如果左⼦树没找到,说明都在右⼦树,如果两个都分别存在,说明当前节点就是他们的⽗节点。

java

public class Solution68 { public int lowestCommonAncestor(TreeNode root, int p, int q) { TreeNode result = commonAncestor(root, p, q); return result == null ? -1 : result.val; } public TreeNode commonAncestor(TreeNode root, int p, int q) { if (null == root) { return null; } if (root.val == p || root.val == q) { return root; } TreeNode left = commonAncestor(root.left, p, q); TreeNode right = commonAncestor(root.right, p, q); if (left == null) { return right; } else if (right == null) { return left; } else { return root; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/30 2:24:35

芯片测试治具关键组成部分和设计考虑:测试程序

在芯片制造过程中&#xff0c;测试治具起着至关重要的作用&#xff0c;它能确保芯片的性能和质量符合标准。深圳市鸿怡电子有限公司&#xff08;HMILU&#xff09;作为集科研、生产、销售于一体的技术型高新企业&#xff0c;在芯片测试座、老化座等产品领域深耕 23 年&#xff…

作者头像 李华
网站建设 2026/6/30 2:23:46

搭建Hermes+Obsidian,我搞定了这辈子最值的本地知识库,从安装到测试全流程讲解!你缺的不是好内容,是一个能帮你记住的AI

不知道你们有没有跟我一样的感受&#xff0c;那就是来自各个平台的收藏夹&#xff0c;长年累月积累下来&#xff0c;多的都害怕去点开看了&#xff0c;可以说是多的可以吃灰了。但是偶尔要用的时候&#xff0c;又根本想不起来收藏在哪里了。 爱收藏是好事&#xff0c;但是想回去…

作者头像 李华
网站建设 2026/6/30 2:21:49

相处的艺术:尊重与边界

在人际关系中&#xff0c;尊重彼此与保持边界是重要的相处原则。它就像一道无形的屏障&#xff0c;既保护着个人的独立空间&#xff0c;又维系着人与人之间的和谐。 尊重&#xff0c;是相处的基石。它意味着认可每个人都是独立的个体&#xff0c;有着自己的思想、情感和选择。无…

作者头像 李华
网站建设 2026/6/30 2:20:29

好用的乒乓球培训公司

在众多体育运动中&#xff0c;乒乓球作为我国的“国球”&#xff0c;一直备受大众喜爱。无论是青少年想要提升技能&#xff0c;还是成年人希望锻炼身体、享受运动乐趣&#xff0c;选择一家专业靠谱的乒乓球培训公司至关重要。今天&#xff0c;就为大家推荐一家值得信赖的乒乓球…

作者头像 李华
网站建设 2026/6/30 2:18:20

隧道代理适合跨境访问吗?3年实测解答你的所有疑问

我前两年帮做跨境的朋友梳理网络方案&#xff0c;发现超过一半的新手都会问同一个问题&#xff1a;隧道代理适合跨境访问吗&#xff1f;不少人分不清不同代理方案的区别&#xff0c;要么花了冤枉钱&#xff0c;要么选不对方案导致访问出问题。今天就把我这几年实测总结的干货整…

作者头像 李华