题目:
给定一颗树和两个a、b节点,返回a和b的最低公共祖先
1、解决方案1:
1.1、思路:
1.2、代码:
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
//方案1:利用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节点一直往上找,放入到set集合中,直至找不到父亲节点
while (parentMap.get(cur) != null) {
cur = parentMap.get(cur);
o1Set.add(cur);
}
cur = o2;
//一直找o2的父亲节点,然后去set集合判断是否存在,如果存在,说明找到了最低的公共祖先
while (!o1Set.contains(cur)) {
cur = parentMap.get(cur);
}
return cur;
}
//填充hashMap
//key:当前节点,value:当前节点的父节点
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);
}
}
2、解决方案2
2.1、思路:
2.2、代码:
//方案2:
public static Node lowestAncestor2(Node head, Node o1, Node o2) {
return process(head, o1, o2).ans;
}
public static class Info {
//以该节点为头的子树找到了o1和o2的最低的公共祖先
public Node ans;
//以该节点为头的子树找到了o1
public boolean findO1;
//以该节点为头的子树找到了o2
public boolean findO2;
public Info(Node a, boolean f1, boolean f2) {
ans = a;
findO1 = f1;
findO2 = f2;
}
}
public static Info process(Node head, Node o1, Node o2) {
if (head == null) {
return new Info(null, false, false);
}
Info leftInfo = process(head.left, o1, o2);
Info rightInfo = process(head.right, o1, o2);
boolean findO1 = head == o1 || leftInfo.findO1 || rightInfo.findO1;
boolean findO2 = head == o2 || leftInfo.findO2 || rightInfo.findO2;
Node ans = null;
// 左树的ans不为空,那么右树的ans一定为空。不可能俩同时都不为空
if (leftInfo.ans != null) {
ans = leftInfo.ans;
}
if (rightInfo.ans != null) {
ans = rightInfo.ans;
}
//如果左右子树都没有找到最低的公共祖先
//但是findO1和findO2同时为true,那么当前head节点就是最低的公共祖先
if (ans == null) {
if (findO1 && findO2) {
ans = head;
}
}
return new Info(ans, findO1, findO2);
}