题目1509:树中两个结点的最低公共祖先
时间限制:1 秒
内存限制:128 兆
特殊判题:否
提交:203
解决:57
-
题目描述:
-
给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。
-
输入:
-
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数。
其中每个测试样例包括两行,第一行为一个二叉树的先序遍历序列,其中左右子树若为空则用0代替,其中二叉树的结点个数node_num<10000。
第二行为树中的两个结点的值m1与m2(0<m1,m2<10000)。
-
输出:
-
对应每个测试案例,
输出给定的树中两个结点的最低公共祖先结点的值,若两个给定结点无最低公共祖先,则输出“My God”。
-
样例输入:
-
2 1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0 6 8 1 2 4 6 0 0 7 0 0 5 8 0 0 9 0 0 3 0 0 6 12
-
样例输出:
-
2 My God
package Tree; import java.util.Iterator; import java.util.LinkedList; import java.util.Scanner; /** * @Title: Tree_findCommonAncestor.java * @Package Tree * @Description: Design an algorithm and write code to find the first common * ancestor of two nodes in a binary tree Avoid storing additional * nodes in a data structure NOTE: This is not necessarily a * binary search tree * @author nutc * @date 2013-7-23 上午9:27:14 * @version V1.0 */ public class Tree_findCommonAncestor2 { public static void main(String args[]){ int n; Scanner sc = new Scanner(System.in); n = sc.nextInt(); sc.nextLine(); //非常重要,读取多出来的回车! while(n>0){ String[] str = sc.nextLine().split(" "); int [] num = new int[str.length]; for(int i=0;i<num.length;i++){ num[i]=Integer.parseInt(str[i]); } FatherNode root = buildTree(num); // root.display(); int n1,n2 ; n1 = sc.nextInt(); n2 = sc.nextInt(); sc.nextLine(); //非常重要,读取多出来的回车! FatherNode com = findCom(root,n1,n2); if(com!=null) System.out.println(String.valueOf(com.value)); else{ System.out.println("My God"); } n--; } } public static FatherNode buildTree(int[] num){ if(num==null) return null; FatherNode root = new FatherNode(num[0]); FatherNode now = root; int index=1; while(index<num.length){ // System.out.println(now.value); if(num[index]!=0){ if(now.left==null){ //全部写反了。。。写成了 != now.left = new FatherNode(num[index]); now.left.father = now; //父亲和儿子 不是可逆的!!! now = now.left; index ++; }else if(now.right==null){ now.right = new FatherNode(num[index]); now.right.father = now; //父亲和儿子 不是可逆的!!! now = now.right; index++; }else{ now = now.father; } }else{ now = now.father; index+=2; } } return root; } public static FatherNode findCom(FatherNode root,int n1,int n2){ if(root==null) return null; LinkedList<FatherNode> list1 = new LinkedList<FatherNode>(); LinkedList<FatherNode> list2 = new LinkedList<FatherNode>(); findList(root,n1,list1); findList(root,n2,list2); // System.out.println(list1.toString()); Iterator<FatherNode> it1 = list1.iterator(); //要限定类型啊亲!!!啊亲!!! Iterator<FatherNode> it2 = list2.iterator(); FatherNode last = null; while(it1.hasNext() && it2.hasNext()){ FatherNode f1 = it1.next(); //不是 it2 = it2.next(); FatherNode f2 = it2.next(); //必须把node取出来比较,不能直接比较 it1 和 it2!!! // System.out.println(f1+" -- "+f2); if(f1 == f2){ last = f1; }else{ break; } } return last; } public static boolean findList(FatherNode root,int n,LinkedList<FatherNode> list){ if(root ==null) return false; list.add(root); if(root.value == n){ return true; } boolean iffound = false; iffound = findList(root.left,n,list); if(!iffound) iffound = findList(root.right,n,list); if(!iffound) list.removeLast(); //remove 默认山第一个 return iffound; } public static class FatherNode { FatherNode left; FatherNode right; FatherNode father; int value; public FatherNode(int v) { value = v; father = null; left = right = null; } public void display() { System.out.print("当前" + value); if (left != null) { System.out.print(" 左边" + left.value); } if (right != null) { System.out.print(" 右边" + right.value); } System.out.println(); if (left != null) left.display(); if (right != null) right.display(); } public void addLeft(FatherNode n){ left = n; n.father = this; } public void addRight(FatherNode n){ right = n; n.father = this; } } }