题目:
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
输入:
给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5]
root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8;输出:6; root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4输出:8;
思路:首先得明白二叉搜索树的性质:即根节点的左子树一定比根节点小,右子树一定比根节点大,在明白这一点后这道题目的做法也就呼之欲出了。由性质出发,我们可以列出三个式子。
1.if(root->val>q->val&&root->val>p->val) 此时就可以明确此节点的左子树一定存在一个我们要找的点,所以我们就继续递归
2.if(root->val<q->val&&root->val<p->val) 此时为根节点的值全小于给定节点的值,那么此时继续递归右子树
3.如果既不满足1又不满足2,那就意味着此时给定的两个结点必定在目前根节点的两个子树中,所以返回该节点
完整代码:
if(!root)return NULL;
if(root->val>p->val&&root->val>q->val)
return lowestCommonAncestor(root->left,p,q);
else if(root->val<p->val&&root->val<q->val)
return lowestCommonAncestor(root->right,p,q);
else
return root;
}
上面是二叉搜索树所对应的代码,这道题之所以能够轻易做出完全是基于搜索树对应的性质,那如果题目给的不是搜索树我们又该如何解决。
这到力扣上的题刚好涉及到了普通二叉树如何寻找公共祖先的问题,没有了线索二叉树,我们就不能运用上面的方法去思考。但是我们可以从图像出发,研究规律。从树中我们知道,如果题目给定的两个结点刚好在根节点的左和右,那么根节点就是我们要找的结点;那如果两个结点刚好同时在左或者同时在右出现,这种情况下一定有一边子树是遍历不到该节点的。说到这,想必大家已经又思路了,就是基于根节点递归左子树和右子树,如果递归到头时有一边是空的,那么根节点就是答案,如果不是,就分类判断。
下面是代码:
if(!root)return NULL;
if(root->val==p->val||root->val==q->val)
return root;
TreeNode* lt=lowestCommonAncestor(root->left,p,q);
TreeNode* rt=lowestCommonAncestor(root->right,p,q);
if(lt&&rt)
return root;
else if(lt)
return lt;
else if(rt)
return rt;
else
return NULL;