No.236 Lowest Common Ancestor of a Binary Tree
Problem:
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Explanation:
找出两个结点的最近公共祖先。
My Thinking:
My Solution:
Optimum Thinking:
- 使用递归,当碰到p或q后,返回true,直到某个结点的左右都返回true,说明其左、右子树包含了p和q,且该结点是p和q的最近祖先。
- 使用迭代,将所有父子结点存入map中,并在找到p和q时将其祖先全部存入到set中,然后找到共同的祖先即可。
- 网友给的递归思路,两个结点有两种情况:1,两个结点分别位于当前结点的左右子树,则直接返回当前结点;2,两个结点都位于当前结点的左子树(右子树),则返回当前结点的左结点(右结点);
Optimum Solution:
(1)
class Solution {
private TreeNode result=null;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
recursive(root,p,q);
return result;
}
public boolean recursive(TreeNode root, TreeNode p, TreeNode q){
if(root==null)
return false;
int left=recursive(root.left,p,q)?1:0;
int right=recursive(root.right,p,q)?1:0;
int mid=(root==p || root==q)?1:0;//祖先结点可以是自己。
if(mid+left+right>=2)
result=root;
return (mid+left+right>0);
}
}
(2)
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
Deque<TreeNode> stack=new ArrayDeque<>();
Map<TreeNode,TreeNode> parent=new HashMap<>();
parent.put(root,null);
stack.push(root);
while (!parent.containsKey(p) || !parent.containsKey(q)) {
TreeNode node = stack.pop();
if (node.left != null) {
parent.put(node.left, node);//将该结点子节点和该结点作为键值对存入
stack.push(node.left);
}
if (node.right != null) {
parent.put(node.right, node);
stack.push(node.right);
}
}
Set<TreeNode> ancestors = new HashSet<>();
while (p != null) {//将p及其祖先都存入ancestors中
ancestors.add(p);
p = parent.get(p);
}
while (!ancestors.contains(q))//在ancestors中找到q的祖先,由于所有结点都不相同,且存入set中,所以只有唯一解。
q = parent.get(q);
return q;
}
}
(3)
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;//找到p和q所在结点
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
return left == null ? right : right == null ? left : root;
//如果right是空,说明p或q在左子树或是它自己。
}