原题链接:236. Lowest Common Ancestor of a Binary Tree
【思路-Java】dfs|递归实现
本题是二叉树的深度遍历的典型应用,基础还是二叉树的遍历。
以根节点为起点,往左右分支上寻找,如果找到了 p 或 q 节点,则返回该节点。否则,继续向叶子节点寻找,假想一下,如果一直递归到 null 还是找不到该节点,那么说明这个分支上不存在该节点。
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//如果找到 p 或者 q 那么就没有必要接着递归,因为共同祖先只可能是该节点或该节点祖先
//如果 root 为空了,说明这条路径上不可能有 p 或 q 节点,返回空
if(root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q); //往左分支上寻找
TreeNode right = lowestCommonAncestor(root.right, p, q); //往右分支上寻找
if(left != null && right != null) return root; //说明 p 和 q 是分布在 root 两侧,返回即可
if(left != null) return left; //说明在 left 分支上找到 p 或 q 节点,返回即可
return right; //否则返回 right
}
}
31 / 31
test cases passed. Runtime: 13 ms Your runtime beats 30.43% of javasubmissions.
【思路2-Java】bfs|非递归实现
需要借用一些数据结构,hashmap 中存放节点及其父节点。采用队列广度遍历,直到 p 和 q 的父亲节点都找到为止,然后找到公共父节点,效率不高,供大家拓宽思路:
public class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
HashMap<TreeNode, TreeNode> parent = new HashMap<>();
parent.put(root, null);
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!parent.containsKey(p) || !parent.containsKey(q)) { //找到 p 和 q 的父节点
root = queue.poll();
if(root != null) {
parent.put(root.left, root);
parent.put(root.right, root);
queue.add(root.left);
queue.add(root.right);
}
}
HashSet<TreeNode> set = new HashSet<>();
while(p != null) { //将 p 的所有父节点放入 set 中
set.add(p);
p = parent.get(p);
}
while(!set.contains(q)) { //找到公共父节点就返回
q = parent.get(q);
}
return q;
}
}
31 / 31
test cases passed. Runtime: 36 ms Your runtime beats 5.38% of javasubmissions.