给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 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。因为根据定义最近公共祖先节点可以为节点本身。
说明:
所有节点的值都是唯一的。
p、q 为不同节点且均存在于给定的二叉树中。
最近公共祖先的定义: 设节点 root
为节点 p,q
的某公共祖先,若其左子节点 root.left
和右子节点 root.right
都不是 p,q
的公共祖先,则称 root
是 “最近的公共祖先” 。
根据如上定义,最近公共祖先只有三种情况:
(1)p
和q
分别在root
的子树中,且分别在root
的两侧(分别在左右子树中)
(2)p = root
且 q
在root
的左/右子树中
(3 )q = root
且 p
在root
的左/右子树中
本题给定了两个重要条件:① 树为 二叉搜索树(中序遍历有序) ,② 树的所有节点的值都是 唯一 的。根据以上条件,可方便地判断 p,q
与 root
的子树关系,即:
(1)若 root.val < p.val
,则 p
在 root
右子树 中;
(2)若 root.val > p.val
,则 p
在 root
左子树 中;
(3)若 root.val=p.val
,则 p
和 root
指向 同一节点 。
方法一:迭代
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while(root != null) {
if(root.val < p.val && root.val < q.val) // p,q 都在 root 的右子树中
root = root.right; // 遍历至右子节点
else if(root.val > p.val && root.val > q.val) // p,q 都在 root 的左子树中
root = root.left; // 遍历至左子节点
else break;
}
return root;
}
}
方法二:递归
java代码如下:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root.val < p.val && root.val < q.val)//p,q都在root的右子树
return lowestCommonAncestor(root.right, p, q);
if(root.val > p.val && root.val > q.val)//p,q都在root的左子树
return lowestCommonAncestor(root.left, p, q);
return root;
}
}