剑指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 ;
}

剑指Offer - 九度1520 - 树的子结构的更多相关文章

  1. 剑指Offer - 九度1509 - 树中两个结点的最低公共祖先

    剑指Offer - 九度1509 - 树中两个结点的最低公共祖先2014-02-07 01:04 题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样 ...

  2. 剑指Offer - 九度1503 - 二叉搜索树与双向链表

    剑指Offer - 九度1503 - 二叉搜索树与双向链表2014-02-05 23:39 题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树 ...

  3. 剑指Offer - 九度1513 - 二进制中1的个数

    剑指Offer - 九度1513 - 二进制中1的个数2013-11-29 23:35 题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 输入: 输入可能包含多个测试样例. ...

  4. 剑指Offer - 九度1368 - 二叉树中和为某一值的路径

    剑指Offer - 九度1368 - 二叉树中和为某一值的路径2013-11-23 03:46 题目描述: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结 ...

  5. 剑指Offer - 九度1351 - 数组中只出现一次的数字

    剑指Offer - 九度1351 - 数组中只出现一次的数字2013-11-23 01:23 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. ...

  6. 剑指Offer - 九度1350 - 二叉树的深度

    剑指Offer - 九度1350 - 二叉树的深度2013-11-23 00:54 题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的 ...

  7. 剑指Offer - 九度1524 - 复杂链表的复制

    剑指Offer - 九度1524 - 复杂链表的复制2014-02-07 01:30 题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点 ...

  8. 剑指Offer - 九度1508 - 把字符串转换成整数

    剑指Offer - 九度1508 - 把字符串转换成整数2014-02-06 23:46 题目描述: 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 输入: 输入可能包含多个测试样例 ...

  9. 剑指Offer - 九度1504 - 把数组排成最小的数

    剑指Offer - 九度1504 - 把数组排成最小的数2014-02-06 00:19 题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输 ...

随机推荐

  1. 如何在markdown中实现缩进,空格,制表符

    参考 https://stackoverflow.com/questions/6046263/how-to-indent-a-few-lines-in-markdown-markup Markdown ...

  2. Javascript作业—数组去重(要求:原型链上添加函数)

    数组去重(要求:原型链上添加函数) <script> //数组去重,要求:在原型链上添加函数 //存储不重复的--仅循环一次 if(!Array.prototype.unique1){ A ...

  3. 2017.9.15 HTML学习总结---表格table

    2.7 表格<table>的属性: 属性  用途 width         表格宽度 height        表格高度 align         表格水平对齐 border     ...

  4. 一步步做程序优化-讲一个用于OpenACC优化的程序(转载)

    一步步做程序优化[1]讲一个用于OpenACC优化的程序 分析下A,B,C为三个矩阵,A为m*n维,B为n*k维,C为m*k维,用A和B来计算C,计算方法是:C = alpha*A*B + beta* ...

  5. 初尝微信小程序2-基本框架

    基本框架: .wxml :页面骨架 .wxss :页面样式 .js :页面逻辑    描述一些行为 .json :页面配置 创建一个小程序之后,app.js,app.json,app.wxss是必须的 ...

  6. Oracle口令文件管理

    Oracle的口令文件目录 $ORACLE_HOME/dbs/orapw$ORACLE_SID 建立口令文件 orapwd file=$ORACLE_HOME/dba/orapw$ORACLE_SID ...

  7. js字符转数字

    js字符串转数字 转换函数.强制类型转换.利用js变量弱类型转换. 1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只 ...

  8. python实现简单关联规则Apriori算法

    from itertools import combinations from copy import deepcopy # 导入数据,并剔除支持度计数小于min_support的1项集 def lo ...

  9. 路由器基础配置之单臂路由实现vlan间通信

    我们将以上面的拓扑图开始进行配置,目的为设置单臂路由实现vlan间通信,设置4个vlan,pc0,1,2为vlan10 pc3,4,5为vlan20:pc6,7,8为vlan30:server0,1为 ...

  10. 【c学习-3】

    ---恢复内容开始--- #include<stdio.h> int main(){ ]={,,,,}; ; ;i<=;i++){ printf("%d\n",a ...