package com.interview.books.svinterview; import java.util.*; /** * Created_By: stefanie * Date: 14-12-8 * Time: 下午12:35 */ public class SV8_CommonAncestorGenericTree { class GenericTreeNode implements Comparable<GenericTreeNode>{ int val; List<GenericTreeNode> children; @Override public int compareTo(GenericTreeNode o) { if(o == null) return 1; else return this.val - o.val; } } //do the BFS save the parents of each node until found both n1 and n2. //backtrace the first common nodes in the path public GenericTreeNode LCA(GenericTreeNode root, GenericTreeNode n1, GenericTreeNode n2){ if(root == null || n1 == null || n2 == null) return null; HashMap<GenericTreeNode, GenericTreeNode> parents = new HashMap<>(); Queue<GenericTreeNode> queue = new LinkedList(); queue.offer(root); boolean foundN1 = false; boolean foundN2 = false; while(!queue.isEmpty()){ GenericTreeNode node = queue.poll(); if(node == n1) foundN1 = true; else if(node == n2) foundN2 = true; if(foundN1 && foundN2) break; for(GenericTreeNode child : node.children){ parents.put(child, node); queue.add(child); } } if(foundN1 == false || foundN2 == false) return null; Stack<GenericTreeNode> pathN1 = getPath(n1, parents); Stack<GenericTreeNode> pathN2 = getPath(n2, parents); GenericTreeNode common = null; while(!pathN1.isEmpty() && !pathN2.isEmpty()){ GenericTreeNode p1 = pathN1.pop(); GenericTreeNode p2 = pathN2.pop(); if(p1 == p2) common = p1; else break; } return common; } public Stack<GenericTreeNode> getPath(GenericTreeNode node, HashMap<GenericTreeNode, GenericTreeNode> parents){ Stack<GenericTreeNode> path = new Stack<>(); path.add(node); if(parents.containsKey(node)){ path.add(parents.get(node)); } return path; } }