题目描述
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目分析
二叉搜索树的性质:
- left.val < root.val < right.val;
- 若存在p,q,root,使得p.val < root.val < q.val, 则root一定为p和q最小公共祖先。
代码实现
- 递归
/**
* 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) {
// base case
if(root == null) {
return null;
}
if(root.val > p.val && root.val > q.val) {
return lowestCommonAncestor(root.left, p, q);
}
if(root.val < p.val && root.val < q.val) {
return lowestCommonAncestor(root.right, p, q);
}
// 给定二叉搜索树,若root.val > left.val, root.val < right.val, 则root一定是left和right最小公共祖先
return root;
}
}
时间复杂度: O(n)。n为二叉树节点个数,最差情况为二叉搜索树退化为链表,需要递归n层;最好情况二叉树为满二叉树,二叉树高度为logn, 时间复杂度为O(logn)。
空间复杂度: O(n)。递归深度达到树的高度n。
- 迭代
当节点不为空时,根据BST性质分别不断迭代去左右子树寻找,注意break跳出循环。
/**
* 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){
while(root != null){
if (root.val < p.val && root.val < q.val){
root = root.right;
}
else if (root.val > p.val && root.val > q.val){
root = root.left;
}
else break;
}
return root;
}
}
时间复杂度: O(n)。n为二叉树节点个数,最差情况为二叉搜索树退化为链表,需要循环n层;最好情况二叉树为满二叉树,二叉树高度为logn, 时间复杂度为O(logn)。
空间复杂度: O(1)。只是用了root, p, q给定的常数空间。