剑指Offer - 九度1520 - 树的子结构
2013-11-30 22:17
题目描述:

输入两颗二叉树A,B,判断B是不是A的子结构。

输入:

输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行一个整数n,m(1<=n<=1000,1<=m<=1000):n代表将要输入的二叉树A的节点个数(节点从1开始计数),m代表将要输入的二叉树B的节点个数(节点从1开始计数)。接下来一行有n个数,每个数代表A树中第i个元素的数值,接下来有n行,第一个数Ki代表第i个节点的子孩子个数,接下来有Ki个树,代表节点i子孩子节点标号。接下来m+1行,与树A描述相同。

输出:

对应每个测试案例,
若B是A的子树输出”YES”(不包含引号)。否则,输出“NO”(不包含引号)。

样例输入:
7 3
8 8 7 9 2 4 7
2 2 3
2 4 5
0
0
2 6 7
0
0
8 9 2
2 2 3
0
0 1 1
2
0
3
0
样例输出:
YES
NO
提示:

B为空树时不是任何树的子树。

题意分析:
  给定两棵二叉树,判断树B是否为树A的子结构。题目中的输入输出方式有点问题,不过无伤大雅。对于“子结构”的话,可以参考下面的例子:
    

  只要能把B树和A树中的一部分重合起来,就定义B树是A树的子结构。递归求解即可,细节应该不需要赘述了。如果A树、B树的节点数分别为m、n,则时间复杂度O(m * n),因为递归过程中对于每个A中的节点,都需要将B树的结构验证一遍,验证失败时可以提前结束递归,但平均复杂度仍是O(n),所以综合起来是O(m * n)。下面是ac代码。
 // 652327    zhuli19901106    1520    Accepted    点击此处查看所有case的执行结果    1048KB    2486B    10MS
//
#include <cstdio>
using namespace std; const int MAXN = ;
int a[MAXN][];
int b[MAXN][];
int c[MAXN];
int na, nb;
int ra, rb; bool is_subtree(const int a[][], const int b[][], int ia, int ib)
{
if(a == NULL || b == NULL){
return false;
}
if(ia < || ia > na - ){
return false;
}
if(ib < || ib > nb - ){
return false;
} if(a[ia][] == b[ib][]){
bool ret1, ret2; if(b[ib][] != -){
ret1 = is_subtree(a, b, a[ia][], b[ib][]);
}else{
ret1 = true;
} if(b[ib][] != -){
ret2 = is_subtree(a, b, a[ia][], b[ib][]);
}else{
ret2 = true;
} return (ret1 && ret2);
}else{
return false;
}
} int main()
{
int i, j;
int x, y; while(scanf("%d%d", &na, &nb) == ){
for(i = ; i < na; ++i){
for(j = ; j < ; ++j){
a[i][j] = -;
}
}
for(i = ; i < nb; ++i){
for(j = ; j < ; ++j){
b[i][j] = -;
}
} for(i = ; i < na; ++i){
scanf("%d", &x);
a[i][] = x;
c[i] = ;
}
for(i = ; i < na; ++i){
scanf("%d", &j);
if(j == ){
scanf("%d", &x);
a[i][] = x - ;
++c[x - ];
}else if(j == ){
scanf("%d%d", &x, &y);
a[i][] = x - ;
a[i][] = y - ;
++c[x - ];
++c[y - ];
}
}
ra = -;
for(i = ; i < na; ++i){
if(c[i] == ){
ra = i;
}
} for(i = ; i < nb; ++i){
scanf("%d", &x);
b[i][] = x;
c[i] = ;
}
for(i = ; i < nb; ++i){
scanf("%d", &j);
if(j == ){
scanf("%d", &x);
b[i][] = x - ;
++c[x - ];
}else if(j == ){
scanf("%d%d", &x, &y);
b[i][] = x - ;
b[i][] = y - ;
++c[x - ];
++c[y - ];
}
}
rb = -;
for(i = ; i < nb; ++i){
if(c[i] == ){
rb = i;
}
} // you can't put this if() up front, if na > 0 && nb == 0, then the input data for a is ignored
if(na <= || nb <= ){
printf("NO\n");
continue;
} if(ra == - || rb == -){
// there is at least one invalid tree
printf("NO\n");
continue;
} for(i = ; i < na; ++i){
if(is_subtree(a, b, i, rb)){
break;
}
}
if(i < na){
printf("YES\n");
}else{
printf("NO\n");
}
} return ;
}

最新文章

  1. 通过一个模拟程序让你明白ASP.NET MVC是如何运行的
  2. uboot环境变量实现分析
  3. aspx aspx.cs
  4. 蛙蛙推荐:快速自定义Boostrap样式
  5. C#中的var类型
  6. Grovvy初识
  7. [linux]BASH 的基本语法
  8. hadoop2.5.2学习及实践笔记(二)—— 编译源代码及导入源码至eclipse
  9. Google Map API 代码示例
  10. a标签加绝对定位在图片上面,a的链接和块状属性block失效,而且是所有IE版本都失效的
  11. mysql 增量导入到elasticsearch
  12. How to Programmatically Add/Delete Custom Options in Magento? - See more at: http://apptha.com/blog/
  13. Delphi中获取Unix时间戳及注意事项(c语言中time()是按格林威治时间计算的,比北京时间多了8小时)
  14. 2017-2018-1 我爱学Java 第一周 作业
  15. linux文件访问权限(像rw-r--rw-是什么意思)
  16. POJ 3104 Drying (经典)【二分答案】
  17. 安装ORACLE高可用RAC集群11g校验集群安装的可行性输出信息
  18. HashMap TreeMap的区别
  19. Yii1.1.16学习记录
  20. dos批量导入不受信任的证书及软件限制策略的应用

热门文章

  1. CEFSharp在anycpu下的编译
  2. Makedown语法说明
  3. CRM, C4C和Hybris的后台作业
  4. Leetcode back(215) to be continue
  5. shell脚本监控URL并自动发邮件
  6. eclips新建Maven Web项目
  7. Compass Card Sales(模拟)
  8. C语言中volatile关键字的作用[转]
  9. nuget打包
  10. javaScript校验图片大小、格式