1.遞歸
2 迭代
棧存儲遍歷結點
HashMap 存儲祖先結點
HashSet 存儲p的祖先結點
找p在q祖先結點中存在的第一個結點;
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private TreeNode ans;
public Solution(){
this.ans = null;
}
private boolean recurseTree(TreeNode curr,TreeNode p,TreeNode q){
if(curr == null){return false;}
//set left
int left = recurseTree(curr.left,p,q) ? 1:0;
int right = recurseTree(curr.right,p,q) ? 1:0;
int mid = (curr == p || curr == q) ? 1:0;
if(left + mid + right >= 2){
this.ans = curr;
}
return (left + mid + right > 0);
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
this.recurseTree(root,p,q);
return this.ans;
}
//解法2 迭代 棧
public TreeNode lowestCommonAncestor2(TreeNode root, TreeNode p, TreeNode q) {
//stack for traversal
Deque<TreeNode> stack = new ArrayDeque<>();
//map for parent pointers
Map<TreeNode,TreeNode> parent = new HashMap<>();
stack.push(root);
parent.put(root,null);
while(!parent.containsKey(p) || !parent.containsKey(q)){
TreeNode node = stack.pop();
//將結點的左右子樹的根加入到parent中
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);
}
}
//存儲p結點的祖先
Set<TreeNode> ancestors = new HashSet<>();
while(p!=null){
ancestors.add(p);
p= parent.get(p);
}
//p的ancestors裏面找和q一樣的公共祖先
while(!ancestors.contains(q)){
q = parent.get(q);
}
return q;
}
}