给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 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 为不同节点且均存在于给定的二叉搜索树中。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
感谢labuladong的详细解法一文秒杀 5 道最近公共祖先问题
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// return lowestCommonAncestorI(root, p, q);
// return lowestCommonAncestorII(root, p, q);
return lowestCommonAncestorIII(root, p, q);
}
//方法二:迭代,时间复杂度O(N),空间复杂度O(1)
private TreeNode lowestCommonAncestorIII(TreeNode root, TreeNode p, TreeNode q) {
TreeNode cur = root;
while (true) {
if (cur.val > p.val && cur.val > q.val) {
cur = cur.left;
} else if (cur.val < p.val && cur.val < q.val) {
cur = cur.right;
} else {
break;
}
}
return cur;
}
//方法二:递归,时间和空间复杂度O(N)
private TreeNode lowestCommonAncestorII(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
if (root.val > p.val && root.val > q.val) {
return lowestCommonAncestorII(root.left, p, q);
}
if (root.val < p.val && root.val < q.val) {
return lowestCommonAncestorII(root.right, p, q);
}
//val1 <= root.val <= val2则说明当前节点就是LCA
return root;
}
//方法一:递归(参考labuladong解法)
private TreeNode lowestCommonAncestorI(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
//保证val1较小,val2较大
int val1 = Math.min(p.val, q.val);
int val2 = Math.max(p.val, q.val);
return findLCA(root, val1, val2);
}
private TreeNode findLCA(TreeNode root, int val1, int val2) {
if (root == null) {
return null;
}
if (root.val < val1) {
return findLCA(root.right, val1, val2);
}
if (root.val > val2) {
return findLCA(root.left, val1, val2);
}
//val1 < val2,那么val1 <= root.val <= val2则说明当前节点就是LCA
return root;
}
}