【剑指offer】近期公共祖先
转载请注明出处:http://blog.csdn.net/ns_code/article/details/28113959
剑指offer上的最后一题了,一个递归函数调了一下午,才得到正确的结果。
- 题目描写叙述:
-
给定一棵树,同一时候给出树中的两个结点,求它们的最低公共祖先。
- 输入:
-
输入可能包括多个測试例子。
对于每一个測试案例,输入的第一行为一个数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<stdio.h>
#include<stdlib.h>
#include<stdbool.h> typedef struct BTNode
{
struct BTNode *lchild;
struct BTNode *rchild;
int data;
}BTNode,*BTree; /*
前序遍历找出根节点到数据域为val的节点路径,保存在path数组中,
这里index是保存到path数组中的元素的下标,*len用来保存路径长度,
假设能找到val,则返回ture,找不到则返回false
*/
bool GetPreTraversePath(BTree pTree,int val,int *path,int index,int *len)
{
if(pTree == NULL)
{
*len = 0;
return false;
} path[index] = pTree->data;
if(pTree->data == val)
{
*len = index+1;
return true;
}
else
{
bool can;
can = GetPreTraversePath(pTree->lchild,val,path,index+1,len);
if(!can)
can = GetPreTraversePath(pTree->rchild,val,path,index+1,len);
return can;
}
} /*
获取两个路径的最后一个公共节点,
因为对树的先序遍历的结果中,前面一定有些节点同样,因此一定能找到最后一个同样节点
*/
int GetFirstCommonNode(int *path1,int len1,int *path2,int len2)
{
int shortLen = len1<len2 ? len1:len2;
int i;
for(i=0;i<shortLen;i++)
{
if(path1[i] != path2[i])
break;
}
return path1[i-1];
} /*
依据先序遍历序列创建二叉树,因为可能改变根节点的指向,因此传入BTNode的二级指针
*/
void CreateBTree(BTree *pRoot)
{
int data;
scanf("%d",&data);
if(data == 0)
*pRoot = NULL;
else
{
*pRoot = (BTree)malloc(sizeof(BTNode));
if(*pRoot == NULL)
exit(EXIT_FAILURE);
(*pRoot)->data = data;
(*pRoot)->lchild = NULL;
(*pRoot)->rchild = NULL;
CreateBTree(&((*pRoot)->lchild));
CreateBTree(&((*pRoot)->rchild));
}
} /*
销毁二叉树
*/
void DestroyBTree(BTree pRoot)
{
if(pRoot != NULL)
{
if(pRoot->lchild != NULL)
DestroyBTree(pRoot->lchild);
if(pRoot->rchild != NULL)
DestroyBTree(pRoot->rchild);
free(pRoot);
pRoot = NULL;
}
} int main()
{
int path1[10000];
int path2[10000]; int n;
while(scanf("%d",&n) != EOF)
{
int i;
for(i=0;i<n;i++)
{
BTree pRoot = NULL;
CreateBTree(&pRoot); int val1,val2;
scanf("%d %d",&val1,&val2); int len1,len2;
bool can1 = GetPreTraversePath(pRoot,val1,path1,0,&len1);
bool can2 = GetPreTraversePath(pRoot,val2,path2,0,&len2); if(can1 && can2)
printf("%d\n",GetFirstCommonNode(path1,len1,path2,len2));
else
printf("My God\n"); DestroyBTree(pRoot);
}
}
return 0;
}
/************************************************************** Problem: 1509 User: mmc_maodun Language: C Result: Accepted Time:130 ms Memory:920 kb****************************************************************/PS:寻找路径的递归代码调了一个下午,总算搞定了,每次碰到关于树的问题,一般都是三种遍历方式的变种来实现,自然想到递推,有些写着非常easy,有些写着总非常纠结,尤其要返回bool变量的时候,还是太菜,回头要抽个时间把二叉树的递归实现的一些题目好好总结下。
【剑指offer】近期公共祖先的更多相关文章
- 【Java】 剑指offer(68) 树中两个结点的最低公共祖先
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入两个树结点,求它们的最低公共祖先. 思路 该题首先要和面试 ...
- 剑指Offer(第二版)面试案例:树中两个节点的最低公共祖先节点
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/74612786冷血之心的博客) 剑指Offer(第二版)面试案例:树 ...
- 剑指Offer - 九度1509 - 树中两个结点的最低公共祖先
剑指Offer - 九度1509 - 树中两个结点的最低公共祖先2014-02-07 01:04 题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样 ...
- 【剑指Offer面试编程题】题目1509:树中两个结点的最低公共祖先--九度OJ
题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数 ...
- 剑指 Offer 68 - II. 二叉树的最近公共祖先 + 最近公共祖先(LCA)
剑指 Offer 68 - II. 二叉树的最近公共祖先 Offer_68_2 题目详情 题解分析 java代码 package com.walegarrett.offer; /** * @Autho ...
- 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 + 二叉排序树 + 最近公共祖先
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 Offer_68_1 题目描述 方法一:迭代法 由于该题的二叉树属于排序二叉树,所以相对较简单. 只需要判断两个结点是否在根节点的左右子树中 ...
- 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q ...
- 剑指 Offer 68 - II. 二叉树的最近公共祖先
剑指 Offer 68 - II. 二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:"对于有根树 T 的两个结点 p.q,最近 ...
- 剑指offer——树中两个节点的最低公共祖先
代码来源与<剑指offer> 得到从根节点开始到输入的两个结点的两条,需要遍历两次树,每遍历一次的时间复杂度是O(n),得到的两条路径的长度在最差情况时是O(n),通常情况下两条路径的长度 ...
随机推荐
- Oracle 课程八之性能优化之10046事件
Oracle 的事件很多. 具体参考blog: Oracle 跟踪事件 set event 转摘:http://blog.csdn.net/tianlesoftware/archive/2009/12 ...
- [FIX BUG]获取theme中自定义textColor时报的错误
我在Fragment中inflate它都可以,可是一旦使用ListView来inflate就会报错,说找不到我自定义的attr!研究了半天发现是我的inflate的context有问题: view = ...
- 【转】C++ 内存分配(new,operator new)详解
本文主要讲述C++ new运算符和operator new, placement new之间的种种关联,new的底层实现,以及operator new的重载和一些在内存池,STL中的应用. 一 new ...
- poj 1026(置换群)
题意:给你一个变换规则,和一个字符串,问经过k次变换后得到的字符串. 思路:开始的时候试图去找它的整个周期,谁知道周期太大了,各种RE,后来在得知此题需要用置换群来优化,第一次接触置换群学习了下! 代 ...
- Android智能聊天机器人
http://www.tuling123.com/ 注册一个账号,申请一个KEY值.此网站也有文档,可以查看. package com.tulingdemo; import java.te ...
- 将VLC库封装为duilib的万能视频播放控件
转载请说明出处,谢谢~~ 昨天封装好了基于webkit的浏览器控件,修复了duilib的浏览器功能的不足,而我的仿酷狗播放器项目中不光需要浏览器,同时也需要视频播放功能,也就是完成MV的功能.所以我打 ...
- new trip
离开YY已经快一周了,特别感谢以前的老大姚冬和朱云峰,从他俩身上学到了很多.这个决定也经过了很长的纠结,不想再做个犹豫不决的人,所以最后还是坚定了最初的信念,也算是对半年前自己的一个完好交代,以防将来 ...
- 暴雪hash算法
你有一个非常大的字符串数组A,现在又有一个字符串B,需要你去检测B是否存在于A中.最简单粗暴的方法是遍历整个A,但是这个方法投入到实际应用时的运行速度是难以接受的.在没有与其他所有字符串比较前怎么知道 ...
- 在linux上用dd命令实现ghost功能
ghost和g4l 安装操作系统,速度太慢,整个过程太冗长乏味了. 安装过程中,需要回答若干问题,系统需要安装无数个软件,创建和写入无数的文件.因为涉及到大量的文件定位和读写,速度一定是快不起来的. ...
- 转】Maven学习总结(七)——eclipse中使用Maven创建Web项目
原博文出自于: http://www.cnblogs.com/xdp-gacl/p/4054814.html 感谢! 一.创建Web项目 1.1 选择建立Maven Project 选择File -& ...