【题目】给定二叉树的两个二节点node1,node2,找出这两个节点的最低公共祖先节点
【思路】
2种情况
1.node1是node2的祖先节点或者node2是node1的祖先节点
2.node1和node2属于不同的子树
【方法一】利用递归
private Node lowestCommonAncestor(Node head, Node o1, Node o2){
if (head == null || o1 == head || o2 == head){
return head;
}
Node left = lowestCommonAncestor(head.left, o1, o2);
Node right = lowestCommonAncestor(head.right, o1, o2);
if (null != left && null != right){
return head;
}
return left != null ? left : right;
}
【方法二】利用hashmap,将所有节点存入map中,key是每个节点,value是每个节点的父节点,取node1开始回溯,向上遍历,一直到根节点,得到所有节点,放入set中,开始回溯node2,向上遍历,并判断遍历到的节点是否已经存在于set中,遇到的第一个存在的节点就是最低公共祖先节点
private void setMap(Node head, HashMap<Node, Node> fatherMap){
if (null == head){
return;
}
if (null != head.left){
fatherMap.put(head.left, head);
}
if (null != head.right){
fatherMap.put(head.right, head);
}
setMap(head.left,fatherMap);
setMap(head.right,fatherMap);
}
private Node lowestCommonAncestor2(Node head, Node o1, Node o2){
//fatherMap key是当前节点 value是父节点
HashMap<Node,Node> fatherMap = new HashMap<>();
fatherMap.put(head,null);
//将所有节点以及父节点加入到map中,除了根节点的父节点为null,其余都有值
setMap(head,fatherMap);
//o1向上遍历到根节点的所有节点
HashSet<Node> path = new HashSet<>();
while (fatherMap.containsKey(o1)){
path.add(o1);
o1 = fatherMap.get(o1);
}
//o2向上遍历到根节点的节点,直到遇到o1路径中存在节点,则该节点就是最低公共祖先
while (!path.contains(o2)){
o2 = fatherMap.get(o2);
}
return o2;
}
测试代码
public class Code07_LowestCommonAncestor {
public static class Node{
private int value;
private Node left;
private Node right;
public Node(int value) {
this.value = value;
}
}
private static Node lowestCommonAncestor(Node head, Node o1, Node o2){
if (head == null || o1 == head || o2 == head){
return head;
}
Node left = lowestCommonAncestor(head.left, o1, o2);
Node right = lowestCommonAncestor(head.right, o1, o2);
if (null != left && null != right){
return head;
}
return left != null ? left : right;
}
private static Node lowestCommonAncestor2(Node head, Node o1, Node o2){
//fatherMap key是当前节点 value是父节点
HashMap<Node,Node> fatherMap = new HashMap<>();
fatherMap.put(head,null);
//将所有节点以及父节点加入到map中,除了根节点的父节点为null,其余都有值
setMap(head,fatherMap);
//o1向上遍历到根节点的所有节点
HashSet<Node> path = new HashSet<>();
while (fatherMap.containsKey(o1)){
path.add(o1);
o1 = fatherMap.get(o1);
}
//o2向上遍历到根节点的节点,直到遇到o1路径中存在节点,则该节点就是最低公共祖先
while (!path.contains(o2)){
o2 = fatherMap.get(o2);
}
return o2;
}
private static void setMap(Node head, HashMap<Node, Node> fatherMap) {
if (null == head){
return;
}
if (null != head.left){
fatherMap.put(head.left, head);
}
if (null != head.right){
fatherMap.put(head.right, head);
}
setMap(head.left,fatherMap);
setMap(head.right,fatherMap);
}
public static void main(String[] args) {
Node node = new Node(1);
node.left = new Node(2);
node.right = new Node(3);
node.left.left = new Node(4);
node.left.right = new Node(5);
node.right.left = new Node(6);
node.right.right = new Node(7);
node.left.left.left = new Node(8);
node.left.left.right = new Node(9);
Node node1 = lowestCommonAncestor(node, node.left.left.left, node.left.left.right);
Node node2 = lowestCommonAncestor2(node, node.left.left.left, node.left.left.right);
System.out.println(node1.value);
System.out.println(node2.value);
}
}