题目:输入一棵树的两个节点,返回他们的最低公共祖先。
当这棵树是二叉查找树时;
用递归从树的根节点开始遍历。
private TreeNode find(TreeNode node1, TreeNode node2, TreeNode root) {
int val=root.value;
if(val>node1.value&&val>node2.value){
return find(node1,node2,root.left);
}
if(val<node1.value&&val<node2.value){
return find(node1,node2,root.right);
}
return root;
}
如果这棵树只是一颗普通的树,但是拥有指向父节点的指针,
相当于求两个链表的第一个公共节点。
private TreeNode find(TreeNode node1, TreeNode node2) {
int a=0;
int b=0;
TreeNode nodea=node1;
TreeNode nodeb=node2;
while (node1!=null){
node1=node1.parent;
a++;
}
while(node2!=null){
node2=node2.parent;
b++;
}
if(a>b){
for(int i=0;i<a-b;i++){
nodea=nodea.parent;
}
}else if(b>a){
for(int i=0;i<b-a;i++){
nodeb=nodeb.parent;
}
}
while (nodea!=null&&nodeb!=null){
if(nodea==nodeb&&nodea.parent!=null){
return nodeb;
}
nodea=nodea.parent;
nodeb=nodeb.parent;
}
System.out.println("错误");
System.exit(1);
return null;
}
如果这棵树只是一颗普通的树,用遍历的方法,遍历出每一条路径。
public static TreeNode getLastCommonParent(TreeNode root,TreeNode p1,TreeNode p2){
if(root==null||p1==null||p2==null){
return null;
}
LinkedList<TreeNode> path1=new LinkedList<>();
collectNode(root,p1,path1);
LinkedList<TreeNode> path2=new LinkedList<>();
collectNode(root,p2,path2);
return getLastCommonNode(path1,path2);
}
private static TreeNode getLastCommonNode(LinkedList<TreeNode> path1, LinkedList<TreeNode> path2) {
Iterator<TreeNode> it1= path1.iterator();
Iterator<TreeNode> it2= path2.iterator();
TreeNode last=null;
while(it1.hasNext()&&it2.hasNext()){
TreeNode tmp=it1.next();
if(tmp==it2.next()){
last=tmp;
}
}
return last;
}
private static boolean collectNode(TreeNode root, TreeNode node, LinkedList<TreeNode> path) {
if(root==node){
return true;
}
path.add(root);
for(TreeNode child:root.children){
if(collectNode(child,node,path)){
return true;
}
}
//该条路径上没找到节点node就要从路径中移除
path.removeLast();
return false;
}