思路:
1.首先用map表记住这棵树的每一个节点的祖先
2.用set记住o1的祖先
3.在set里面找一下有没有o2,如果有,证明他们的公共祖先是o2
4.如果没有,就从o2开始依次看一下o2的祖先在不在set里,最先找到的就是公共祖先
public static Node lowestAncestor1(Node head, Node o1, Node o2) {
if (head == null) {
return null;
}
// key的父节点是value
HashMap<Node, Node> parentMap = new HashMap<>();
parentMap.put(head, null);
fillParentMap(head, parentMap);
HashSet<Node> o1Set = new HashSet<>();
Node cur = o1;
o1Set.add(cur);
//把所有o1的父节点们都找到 放到o1set
while (parentMap.get(cur) != null) {
cur = parentMap.get(cur);
o1Set.add(cur);
}
cur = o2;
while (!o1Set.contains(cur)) {
cur = parentMap.get(cur);
}
return cur;
}
//把传进来的节点head的左右孩纸都记到map里面
public static void fillParentMap(Node head, HashMap<Node, Node> parentMap) {
if (head.left != null) {
parentMap.put(head.left, head);
fillParentMap(head.left, parentMap);
}
if (head.right != null) {
parentMap.put(head.right, head);
fillParentMap(head.right, parentMap);
}
}
递归方法:
用递归主要是从最底层开始找,所以从底层开始找需要的条件是1.有没有找到A 2.有没有找到B
3.如果找到了 祖先是什么
public static Node lowestAncestor2(Node head, Node a, Node b) {
return process(head, a, b).ans;
}
public static class Info {
public boolean findA;
public boolean findB;
public Node ans;
public Info(boolean fA, boolean fB, Node an) {
findA = fA;
findB = fB;
ans = an;
}
}
public static Info process(Node x, Node a, Node b) {
if (x == null) {
return new Info(false, false, null);
}
Info leftInfo = process(x.left, a, b);
Info rightInfo = process(x.right, a, b);
boolean findA = (x == a) || leftInfo.findA || rightInfo.findA;
boolean findB = (x == b) || leftInfo.findB || rightInfo.findB;
Node ans = null;
if (leftInfo.ans != null) {
ans = leftInfo.ans;
} else if (rightInfo.ans != null) {
ans = rightInfo.ans;
} else {
if (findA && findB) {
ans = x;
}
}
return new Info(findA, findB, ans);
}