题目
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 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, 因为根据定义最近公共祖先节点可以为节点本身。
说明:
- 所有节点的值都是唯一的。
- p、q 为不同节点且均存在于给定的二叉搜索树中。
题解
解题思路
可以分别在树中查找 p 和 q 结点,并且分别使用数组 A、B 记录查找中经过的每个节点,最终两个数组中最后一个相等的元素即为 p 和 q 的最近公共祖先。
但是这种方式需要查找两次,是否可以仅使用一次的查找解决呢?
实际上是可以的。
我们可以同时结合 p 和 q 进行处理。在遍历时,对于每个结点 node,一共有三种情况:
- p 和 q 的值均小于 node.val,说明两者都在 node 的左子树中,当前还没分岔,下一步查找左子树;
- p 和 q 的值均大于 node.val,说明两者都在 node 的右子树中,当前还没分岔,下一步查找右子树;
- 前两种情况均不满足,说明两者要么就是分别在 node 的左右子树,要么其中之一就是 node 本身,无论如何,node 都是我们要找的最近公共祖先,直接返回 node 即可。
代码
/**
* 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) {
return null;
}
TreeNode node = root;
while (true) {
if (p.val < node.val && q.val < node.val) {
node = node.left;
} else if (p.val > node.val && q.val > node.val) {
node = node.right;
} else {
return node;
}
}
}
}
复杂度分析
- 时间复杂度:O(n)
n 是树的结点数。 - 空间复杂度:O(1)
优质项目推荐
推荐一个可用于练手、毕业设计参考、增加简历亮点的项目。
lemon-puls/txing-oj-backend: Txing 在线编程学习平台,集在线做题、编程竞赛、即时通讯、文章创作、视频教程、技术论坛为一体
公众号
有兴趣可以关注公众号一起学习更多的干货哈!