昨天做到一道百度的笔试题,感觉对深搜的理解很有帮助,记录一下。
题目描述
给定两个子树,树节点的数值唯一,问第二棵树是否是第一棵树的子树。是就返回1,否则-1。
给定树节点的定义为:
1 2 3 4 5 6 7 8 9 10 11
| struct tnode { int value; tnode* left; tnode* right; tnode(int v) { //这个构造函数是我为了调试时构造节点方便而写的 value = v; left = NULL; right = NULL; } };
|
考虑思路
这题题意清晰,数据量没有给,应该也不是很大。有其他小伙伴认为可以遍历两个树,得到两个字符串,看是否第二个是第一个的子串。这个想法可能有一定的道理,但是同一个字符串,出现在遍历出来的字符串中的不同位置,也不一定代表就是子树,因为重复的字符串首先在第一个树中要是一个完整的子树才行。要进行这样的判断,太耗时耗力了,还不如考虑直接暴力搜索。
如果是暴搜的话,就要考虑如何搜。最直观的想法是,用第一层dfs枚举母树(第一棵树)的每个节点,然后用第二层dfs(或者bfs也行)遍历当前两棵子树,看是否一模一样。一旦发现相同的,就返回1。最后找不到,就返回-1。
然后就是一些细节问题了,要考虑左右子树完全相同才行。
关键代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| bool issame(tnode* mu_root, tnode* zi_root) { //判断两棵树是否相同 if (mu_root->value != zi_root->value) //当前节点不同,树肯定不同 return 0; if (mu_root->left==NULL && mu_root->right==NULL) { //当前节点相同且母树为叶节点 if (zi_root->left==NULL && zi_root->right==NULL)//子树也是页节点 return 1; return 0; } if (mu_root->left != NULL) { if (zi_root->left == NULL) return 0; bool bl = issame(mu_root->left, zi_root->left); //查看左子树 if (!bl) return 0; } else if (zi_root->left != NULL) //母树没有左子树但子树有 return 0; if (mu_root->right != NULL) { if (zi_root->right == NULL) return 0; bool bl = issame(mu_root->right, zi_root->right); //查看右子树 if (!bl) return 0; } else if (zi_root->right != NULL) //母树没有右子树但子树有 return 0; //左右子树都相同,才算相同 return 1; }
bool dfs(tnode* mu_root, tnode* zi_root) { // 第一层dfs枚举 if (mu_root->left==NULL && mu_root->right==NULL) { //若是叶子节点 //直接返回是否同为叶节点且相等 return mu_root->value==zi_root->value && zi_root->left==NULL && zi_root->right==NULL; } bool res = issame(mu_root, zi_root); //看以mu_root和zi_root为根节点的两个树是否相同 if (res) return 1; //若不同,继续深搜枚举 if (mu_root->left != NULL) { //左子节点 bool res_l = dfs(mu_root->left, zi_root); if (res_l) return 1; } if (mu_root->right != NULL) { //右子节点 bool res_r = dfs(mu_root->right, zi_root); if (res_r) return 1; } return 0; }
int solve(tnode* root1, tnode* root2) { //解决问题的主要函数 bool ans = dfs(root1, root2); if (!ans) return -1; return ans; }
|