《剑指offer》面试题50 树中两个结点的最低公共祖先
2014-04-05 14:12
477 查看
原题请见 http://ac.jobdu.com/problem.php?pid=1509
题目描述:
给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。
分析:
1.首先分析这个树的形态,是不是二叉树,如果是会怎样求解,如果不是的话我们又该如何求解(或者说如何将一棵树转成二叉树)
2.如果这棵树是二叉树的话,那么如何得到这棵树,一般给的是先根遍历,那我们需要根据先根遍历构造出这棵树出来(中根的话怎样,后根遍历的话又怎样)
3.上面说的只是准备工作,现在才是这个问题的解决关键。公共祖先必然存在于根节点到它的路径上,因此我们再求得从根节点到它的路径。
4.分别得到两个节点的路径后,剩下的就是求公共节点了,这个非常容易,我们只需从后向前比较即可。
下面是完整描述:
题目描述:
给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。
输入:
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数。
其中每个测试样例包括两行,第一行为一个二叉树的先序遍历序列,其中左右子树若为空则用0代替,其中二叉树的结点个数node_num<10000。
第二行为树中的两个结点的值m1与m2(0<m1,m2<10000)。
输出:
对应每个测试案例,
输出给定的树中两个结点的最低公共祖先结点的值,若两个给定结点无最低公共祖先,则输出“My God”。
样例输入:
样例输出:
代码如下:
题目描述:
给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。
分析:
1.首先分析这个树的形态,是不是二叉树,如果是会怎样求解,如果不是的话我们又该如何求解(或者说如何将一棵树转成二叉树)
2.如果这棵树是二叉树的话,那么如何得到这棵树,一般给的是先根遍历,那我们需要根据先根遍历构造出这棵树出来(中根的话怎样,后根遍历的话又怎样)
3.上面说的只是准备工作,现在才是这个问题的解决关键。公共祖先必然存在于根节点到它的路径上,因此我们再求得从根节点到它的路径。
4.分别得到两个节点的路径后,剩下的就是求公共节点了,这个非常容易,我们只需从后向前比较即可。
下面是完整描述:
题目描述:
给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先。
输入:
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个数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
代码如下:
#include <iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> typedef struct node //定义树的结构 { int data; struct node *left; struct node *right; }BNode,*BinNode; int path_a[10010]; //保存根节点到给定节点的路径,数组开这么大是防止树退化成一个线性表 int path_b[10010]; int node[10010]; static int flag; //在递归计算根节点到给定节点的路径时,标记是否查找成功,成功为1,否则为0 static int len; static int k=0; //统计树中有多少个非叶节点,用于判定给定节点是否在树中,不在树中的话直接输出"My God" static int length; //用于标记路径中的最后一个节点的位置,即所给定节点在树中的层数,层数从0开始计数 void BuildTree(BNode *&root) { int x; scanf("%d",&x); if(0==x) { root=NULL; } else { root=(BNode *)malloc(sizeof(BNode)); root->data=x; node[k++]=x; BuildTree(root->left); BuildTree(root->right); } } void find_path(BNode *root,int path[],int current,int key,int *flag) { if (*flag==0) { if(root!=NULL && root->data==key) { path[current]=key; length=current; *flag=1; return ; } else { for(int i=0;i<2;i++) { if(*flag==0 && i==0 && root!=NULL) //递归搜索左子树 { path[current]=root->data; find_path(root->left,path,current+1,key,flag); } if (*flag==0 && i==1&&root!=NULL) //递归搜索右子树 { path[current]=root->data; find_path(root->right,path,current+1,key,flag); } } } } } int find_common_father(int *a,int *b,int len1,int len2) //从后向前搜索公共祖先,这样保证是最低的 { int compositon=len1; if(compositon>len2) { compositon=len2; } while (a[compositon]!=*(b+compositon)) { compositon--; } return compositon ; } void Print_Tree(BNode *root) { if (root!=NULL) { //printf("%d ",root->data); Print_Tree(root->left); printf("%d ",root->data); Print_Tree(root->right); } } int main() { int n; scanf("%d",&n); while(n--) { int node_a,node_b; memset(path_a,0,sizeof(path_a)); memset(path_b,0,sizeof(path_b)); k=0; BNode *root;
BuildTree(root); scanf("%d %d",&node_a,&node_b); int answer1=0; int answer2=0; for(int i=0;i<k;i++) //用于判断给定节点node_a和node_b是否在树中 { if(node_a==node[i]) { answer1=1; } if(node_b==node[i]) { answer2=1; } } if(answer1&&answer2) //如果给定节点都在树中的话我们才需要计算路径和最低公共祖先 { int len1,len2; flag=0; len=0; find_path(root,path_a,len,node_a,&flag); len1=length; len=0; flag=0; find_path(root, path_b, len, node_b, &flag); len2=length; int father=find_common_father(path_a, path_b, len1, len2); printf("%d\n",path_a[father]); } else { printf("My God\n"); } } }
相关文章推荐
- 剑指offer 面试题50 树中两个结点的最低公共祖先
- 剑指offer-面试题50-树中两个结点的最低公共祖先
- 《剑指Offer》学习笔记--面试题50:树中两个结点的最低公共祖先
- (剑指Offer)面试题50:树中两个结点的最低公共祖先
- 面试题50 树中两个结点的最低公共祖先
- 【剑指offer】 面试题50: 树中两个结点的最低公共祖先
- 【剑指Offer学习】【面试题50:树中两个结点的最低公共祖先】
- 剑指offer 面试题50—树中两个节点的最低公共祖先
- 剑指offer面试题:求树中两个结点的最低公共祖先
- 【剑指offer】 面试题50: 树中两个结点的最低公共祖先(二叉排序数)
- 面试题50:树中两个结点的最低公共祖先
- 《剑指offer》:[50]树中两个结点的最低公共祖先结点
- 剑指offer——面试题50:树中两个结点的最低公共祖先
- 剑指offer之面试题50树中两个结点的最低公共祖先
- 剑指offer(面试题50)树中两结点的最低公共祖先(C++实现)
- 【剑指Offer学习】【面试题50:树中两个结点的最低公共祖先】
- 【面试题050】树中两个结点的最低公共祖先
- 面试题50:树中两个节点最低公共祖先
- 面试题50 树中两个节点的最低公共祖先LCA(Lowest Common Ancestor )
- 剑指offer(java):求树中两个结点的最低公共祖先