随笔- 509  文章- 0  评论- 151  阅读- 22万 

2014-03-19 05:04

题目:给定两棵二叉树T1和T2,判断T2是否是T1的子树。子树的定义是,以T1的某个节点(可以是T1的根)作为根节点,得到的这棵树和T2一模一样。

解法:首先可以根据节点个数省去一大部分不必要的搜索,然后再递归判断。代码还比较简单,请看下面。

代码:

复制代码
  1 // 4.8 Check if a tree is a subtree of another.
  2 #include <cstdio>
  3 #include <unordered_map>
  4 using namespace std;
  5 
  6 struct TreeNode {
  7     int val;
  8     TreeNode *left;
  9     TreeNode *right;
 10     
 11     TreeNode(int _val = 0): val(_val), left(nullptr), right(nullptr) {};
 12 };
 13 
 14 void constructTree(TreeNode *&root)
 15 {
 16     int val;
 17     
 18     scanf("%d", &val);
 19     if (val == 0) {
 20         root = nullptr;
 21     } else {
 22         root = new TreeNode(val);
 23         constructTree(root->left);
 24         constructTree(root->right);
 25     }
 26 }
 27 
 28 int countNode(TreeNode *root, unordered_map<TreeNode *, int> &node_count)
 29 {
 30     if (root == nullptr) {
 31         return 0;
 32     } else {
 33         node_count[root] = countNode(root->left, node_count) + countNode(root->right, node_count) + 1;
 34         return node_count[root];
 35     }
 36 }
 37 
 38 bool isIdentical(TreeNode *root1, TreeNode *root2)
 39 {
 40     if (root1 == nullptr) {
 41         return root2 == nullptr;
 42     } else if (root2 == nullptr) {
 43         return false;
 44     }
 45     
 46     if (root1->val != root2->val) {
 47         return false;
 48     }
 49     
 50     return isIdentical(root1->left, root2->left) && isIdentical(root1->right, root2->right);
 51 }
 52 
 53 bool hasSubtree(TreeNode *root1, TreeNode *root2, unordered_map<TreeNode *, int> &node_count)
 54 {
 55     if (root1 == nullptr || root2 == nullptr) {
 56         return false;
 57     }
 58     
 59     if (node_count[root1] < node_count[root2]) {
 60         return false;
 61     } else if (node_count[root1] > node_count[root2]) {
 62         return hasSubtree(root1->left, root2, node_count) || hasSubtree(root1->right, root2, node_count);
 63     } else {
 64         return isIdentical(root1, root2);
 65     }
 66 }
 67 
 68 void clearTree(TreeNode *&root)
 69 {
 70     if (root == nullptr) {
 71         return;
 72     }
 73     clearTree(root->left);
 74     clearTree(root->right);
 75     delete root;
 76     root = nullptr;
 77 }
 78 
 79 int main()
 80 {
 81     TreeNode *root1, *root2;
 82     unordered_map<TreeNode *, int> node_count;
 83     
 84     while (true) {
 85         constructTree(root1);
 86         if (root1 == nullptr) {
 87             break;
 88         }
 89         constructTree(root2);
 90         if (root2 == nullptr) {
 91             break;
 92         }
 93         
 94         countNode(root1, node_count);
 95         countNode(root2, node_count);
 96         if(hasSubtree(root1, root2, node_count)) {
 97             printf("Yes\n");
 98         } else {
 99             printf("No\n");
100         }
101         
102         node_count.clear();
103         clearTree(root1);
104         clearTree(root2);
105     }
106     
107     return 0;
108 }
复制代码

 

 posted on   zhuli19901106  阅读(314)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示