【剑指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),通常情况下两条路径的长度 ...
随机推荐
- JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码
本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 提升到 20 (提升了 7 倍) ...
- CCMoveTo 等函数理解
CCMoveTo: 使用CCMoveTo action来让对象从右侧屏幕外移动到屏幕左侧.注意可以通过指定duration参数控制这一过程需要多久,这里我们随机给他2-4秒的时间. CCCallFun ...
- Android引用百度定位API第三方组件后导致其它.so文件无法正常加载的问题
查看当前调试设备CPU架构的方法: adb.exe shell getprop ro.product.cpu.abi (一般返回值为:armeabi-v7a) adb.exe shell getpr ...
- 仿酷狗音乐播放器开发日志十九——CTreeNodeUI的bug修复二(附源码)
转载请说明原出处,谢谢 今天本来打算把仿酷狗播放列表的子控件拖动插入功能做一下,但是仔细使用播放列表控件时发现了几个逻辑错误,由于我的播放 列表控件是基于CTreeViewUI和CTreeNodeUI ...
- 马上着手开发Mac应用程序
你是否想要开发 Mac 应用程序却又不知道从哪里入手?本路线图提供了 Mac 应用程序开发的绝佳起点,即使你已经是一个 iOS 开发专家,本路线图对你依然适用.Apple让开发应用程序和提交应用程序到 ...
- oracle检查点checkpoint信息
1.关于checkpoint的概述 checkpoint是oracle在数据库一致性关闭.实例恢复和oracle基本操作中不可缺少的机制,包含以下相关的含义: A.检查点的位置(checkpoint ...
- JQuery WEB前段开发
JQuery WEB前段开发 Jquery是继prototype之后又一个优秀的Javascript框架.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器(IE 6.0+, FF 1.5+, S ...
- [Hive - Tutorial] Built In Operators and Functions 内置操作符与内置函数
Built-in Operators Relational Operators The following operators compare the passed operands and gene ...
- Android JNI之JAVA调用C/C++层
转载请声明:原文转自:http://www.cnblogs.com/xiezie/p/5929996.html 一.java调用本地函数的开发步骤: 1.编写本地方法的类(可以说是用来叙述本地方法的类 ...
- cos
Apple过于封闭,没啥朋友,这家伙应该比较高傲,曾仅和Intel,IBM and so on..一起玩过!Google过于开放,狐朋狗友,友人泛滥,殃及ecosystem,弊端已显,祸水将至.COS ...