题目描述
给出二叉树中的两个节点,查找其最低的公共祖先。
递归解法
解题思路,递归时,就要把可能的情况列出来
1.和给出的头节点有关,左树找出一个节点,右树找出另外一个节点。
2.左树找出两个节点,
3.在右树找出两个节点
根据上面情况,我们定义每次递归需要的结果,是否找到a节点,是否找到b节点,是否找到最低公共祖先
定义一个二叉树
public class Node{
int val;
Node left;
Node right;
public Node(int val) {
this.val = val;
}
}
定义消息体
public class Info{
boolean findA;
boolean findB;
Node cur;
public Info(boolean findA, boolean findB, Node cur) {
this.findA = findA;
this.findB = findB;
this.cur = cur;
}
}
递归过程
public static Info process(Node head,Node a,Node b){
if (head == null){
return new Info(false,false,null);
}
Info left = process(head.left,a,b);
Info right = process(head.right,a,b);
boolean findA = head == a || left.findA || right.findA;
boolean findB = head == b || left.findB || right.findB;
Node cur = null;
if (left.cur != null){
cur = left.cur;
} else if (right.cur != null) {
cur = right.cur;
}else {
if (findA && findB){
cur = head;
}
}
return new Info(findA,findB,cur);
}
//调用递归
public static Node lowestAncestor(Node head, Node a, Node b) {
return process(head, a, b).cur;
}
常规解法
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);
while (parentMap.get(cur) != null) {
cur = parentMap.get(cur);
o1Set.add(cur);
}
cur = o2;
while (!o1Set.contains(cur)) {
cur = parentMap.get(cur);
}
return cur;
}
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);
}
}
二叉树其他经典题目
判断是不是搜索二叉树
求出二叉树的最大宽度