剑指OFFER之树的子结构(九度OJ1520)

题目描述:




输入两颗二叉树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为空树时不是任何树的子树。

解题思路:


  这道题有个坑,首先题目要求n与m的范围不能为0,但是测试用例中第三个和第四个有可能分别是第一个树空和第二个数空的特殊情况。因此,要特别注意这里,在scanf("%d
%d",&n,&m)的时候对mn注意限制的范围。

  另外用例并没有给出单个叶子的情况,这时注意,当输入为1时,只有一个节点,并且是左子树节点。

  例如当只有一个孩子时输入的是

  

孩子节点的数目 左边孩子的编号

  另外就是这个题目的主要思想了。首先我们采用的仍然是上次题目使用的结构的树,主要思想就是遍历左边这颗树的没个元素,与右边的树进行比较。如果不同,就再比较左边的孩子节点。一直到遍历完所有的树。

  在进行比较时,判断右边的树是否为空,以及左边的判断顶点是否为空,一旦发现比较的元素不同,就证明比较失败。

  主要的代码,模仿书上代码进行,自己写的总出BUG,哎。


int testForCompare(TreeArr *t1,int t1i,TreeArr *t2){
int result = 0;
if(t1i != 0 && t2->arr[0].num != 0){
if(t1->arr[t1i].num == t2->arr[1].num)
result = compare(t1,t1i,t2,1);
if(!result)
result = testForCompare(t1,t1->arr[t1i].lchild,t2);
if(!result)
result = testForCompare(t1,t1->arr[t1i].rchild,t2);
}
return result;
};
int compare(TreeArr *t1,int t1i,TreeArr *t2,int t2i){
if(t2i == 0)
return 1;
if(t1i == 0)
return 0;
if(t1->arr[t1i].num != t2->arr[t2i].num)
return 0;
return compare(t1,t1->arr[t1i].lchild,t2,t2->arr[t2i].lchild)&&compare(t1,t1->arr[t1i].rchild,t2,t2->arr[t2i].rchild);
}

全部代码:


#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 1005
typedef struct treeelement{
int num;
int lchild;
int rchild;
}TreeElement;
typedef struct treearr{
TreeElement arr[MAXSIZE];
}TreeArr;
int testForCompare(TreeArr *t1,int t1i,TreeArr *t2);
int compare(TreeArr *t1,int t1i,TreeArr *t2,int t2i);
int main(void){
int n,m,i,nchild,n1,n2;
TreeArr *t1 = (TreeArr *)malloc(sizeof(TreeArr));
TreeArr *t2 = (TreeArr *)malloc(sizeof(TreeArr));
while(scanf("%d %d",&n,&m) != EOF){
//....initialize the tree
for(i=0;i<1000;i++){
t1->arr[i].num = 0;
t1->arr[i].lchild = 0;
t1->arr[i].rchild = 0;

t2->arr[i].num = 0;
t2->arr[i].lchild = 0;
t2->arr[i].rchild = 0;
}
t1->arr[0].num = n;
t2->arr[0].num = m;
//.....input the first tree
for(i=1;i<=n;i++){
scanf("%d",&t1->arr[i].num);
}
for(i=1;i<=n;i++){
scanf("%d",&nchild);
if(nchild == 2){
scanf("%d %d",&n1,&n2);
t1->arr[i].lchild = n1;
t1->arr[i].rchild = n2;
}else if(nchild == 1){//不确定是怎么输入的?样例中没有这项
scanf("%d",&n1);
t1->arr[i].lchild = n1;
}else if(nchild == 0){

}
}
//........input the second tree
for(i=1;i<=m;i++){
scanf("%d",&t2->arr[i].num);
}
for(i=1;i<=m;i++){
scanf("%d",&nchild);
if(nchild == 2){
scanf("%d %d",&n1,&n2);
t2->arr[i].lchild = n1;
t2->arr[i].rchild = n2;
}else if(nchild == 1){//不确定是怎么输入的?样例中没有这项
scanf("%d",&n1);
t2->arr[i].lchild = n1;
}else if(nchild == 0){
}
}
//testing for compare
if(testForCompare(t1,1,t2))
printf("YES\n");
else
printf("NO\n");
}
return 0;
};
int testForCompare(TreeArr *t1,int t1i,TreeArr *t2){
int result = 0;
if(t1i != 0 && t2->arr[0].num != 0){
if(t1->arr[t1i].num == t2->arr[1].num)
result = compare(t1,t1i,t2,1);
if(!result)
result = testForCompare(t1,t1->arr[t1i].lchild,t2);
if(!result)
result = testForCompare(t1,t1->arr[t1i].rchild,t2);
}
return result;
};
int compare(TreeArr *t1,int t1i,TreeArr *t2,int t2i){
if(t2i == 0)
return 1;
if(t1i == 0)
return 0;
if(t1->arr[t1i].num != t2->arr[t2i].num)
return 0;
return compare(t1,t1->arr[t1i].lchild,t2,t2->arr[t2i].lchild)&&compare(t1,t1->arr[t1i].rchild,t2,t2->arr[t2i].rchild);
}
/**************************************************************
Problem: 1520
User: xhalo
Language: C
Result: Accepted
Time:10 ms
Memory:912 kb
****************************************************************/

剑指OFFER之树的子结构(九度OJ1520)

时间: 2024-07-30 05:35:35

剑指OFFER之树的子结构(九度OJ1520)的相关文章

【剑指offer】树的子结构

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25907685 剑指offer第18题,九度OJ上测试通过! 题目描述: 输入两颗二叉树A,B,判断B是不是A的子结构. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行一个整数n,m(1<=n<=1000,1<=m<=1000):n代表将要输入的二叉树A的节点个数(节点从1开始计数),m代表将要输入的二叉树B的节点个数(节点从1开始计数).

剑指OFFER之丑数(九度OJ1214)

题目描述: 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7.习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 输入: 输入包括一个整数N(1<=N<=1500). 输出: 可能有多组测试数据,对于每组数据,输出第N个丑数. 样例输入: 3 样例输出: 3 解题思路: 最简单的思路是,从1到大数,每个数都检测一遍是否是丑数,检测方法可以考虑 int ugly(int number){ if(number%2 == 0

剑指OFFER之反转链表(九度OJ1518)

题目描述: 输入一个链表,反转链表后,输出链表的所有元素.(hint : 请务必使用链表) 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000):代表将要输入的链表的个数.输入的第二行包含n个整数t(0<=t<=1000000):代表链表元素. 输出: 对应每个测试案例,以此输出链表反转后的元素,如没有元素则输出NULL. 样例输入: 5 1 2 3 4 5 0 样例输出: 5 4 3 2 1 NULL 解题思路:

剑指OFFER之矩形覆盖(九度OJ1390)

题目描述: 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入包括一个整数n(1<=n<=70),其中n为偶数. 输出: 对应每个测试案例, 输出用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有的方法数. 样例输入: 4 样例输出: 5 解题思路: 观察题目中的矩形,2*n的,是个长条形.本来脑中想象的是复杂的华容道,但是既然只是简单的长条形,那么

剑指OFFER之重建二叉树(九度OJ1385)

题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为一个整数n(1<=n<=1000):代表二叉树的节点个数. 输入的第二行包括n个整数(其中每个元素a的范围为(1<=a<=1000)):代表二叉树的前序

剑指offer之树的子结构

题目: 树的子结构 链接: https://www.nowcoder.com/practice/6e196c44c7004d15b1610b9afca8bd88?tpId=13&tqId=11170&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 题目描述: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 思路: 分为两步: 第一步:

python剑指offer 实现树的子结构

题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) # -*- coding:utf-8 -*- # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: def HasSubtree(self, pRoot1, pRoot2): # write code here if not

剑指Offer 17. 树的子结构 (二叉树)

题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 题目地址 https://www.nowcoder.com/practice/6e196c44c7004d15b1610b9afca8bd88?tpId=13&tqId=11170&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 思路 如果树1或树2为空时,返回False 在树

剑指offer:树的子结构

题目描述输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: def HasSubtree(self, pRoot1, pRoot2): def helper(root1, root2): # 如果root2已经遍历完了,说明root2的每一个节点都能在p