题目描述:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。
思路:给定的 p ,q 结点分别有以下几种情况:
- p 或者 q 就是 root ,那么返回 root。如结点 3 和结点 8 的最近公共祖先就是结点 3
- p 和 q 不在同一个子树上,返回 root。如结点6 和结点 4 的最近公共祖先是 结点 5
- p 和 q 都在左子树,递归到左子树解决
- p 和 q 都在右子树,递归到右子树解决
还有一个问题就是如何知道 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 boolean search(TreeNode root,TreeNode t){
//查找 t 结点是否在 root 树中
if(root == null){
return false;
}
if(root == t){//这里直接进行相等判断,代表的是看这两个引用是否指向同一个结点,而不是之前写过的判断某个值是否在树中
return true;
}
if(search(root.left,t)){
return true;
}
return search(root.right,t);
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == p || root == q){
return root;
}
boolean pIsInLeft = search(root.left,p);
boolean qIsInLeft = search(root.left,q);
if(pIsInLeft && qIsInLeft){
return lowestCommonAncestor(root.left,p,q);
}
if(!pIsInLeft && !qIsInLeft){
return lowestCommonAncestor(root.right,p,q);
}
return root;
}
}