在当前二叉树中查询指定子树(C++)
->题目重述:
本题的数据结构:
裁判程序中的二叉树结构体样式:
/**
Definition for a binary tree node.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
*/
方法一:化成字符串检测
class Solution {
private:
string szTtree;
string szStree;
public:
void TreeToString(struct TreeNode* root,string& s){
if(root == NULL){
s+=" ";
return;
}
s+=("a"+to_string(root->val)+"a");
TreeToString(root->left,s);
TreeToString(root->right,s);
}
bool isSubtree(TreeNode* s, TreeNode* t) {
TreeToString(s,szStree);
TreeToString(t,szTtree);
if(strstr(szStree.c_str(),szTtree.c_str()) != NULL) return true;
else return false;
}
};
ac结果:
结果显示效果并不太好,原因在于字符串转化消耗太多时间,不仅仅是访问两个树的复杂度,还要加上字符串拼接的时间复杂度。最后的最后还要加上一个字符串匹配的复杂度。----总体来说非常差
方法二:暴力dfs逐项查找
这个方法是官方给出来的,思路很贱单,哈哈,就是暴力遍历,不过官方代码写的很简洁,值得学习利用逻辑运算简化代码长度。
class Solution {
public:
bool check(TreeNode *o, TreeNode *t) {
if (!o && !t) return true;
if ((o && !t) || (!o && t) || (o->val != t->val)) return false;
return check(o->left, t->left) && check(o->right, t->right);
}
bool dfs(TreeNode *o, TreeNode *t) {
if (!o) return false;
return check(o, t) || dfs(o->left, t) || dfs(o->right, t);
}
bool isSubtree(TreeNode *s, TreeNode *t) {
return dfs(s, t);
}
};
想不到的是暴力计算效果出奇的好
分析一下:时间复杂度最差需要访问两次S树,一次T树,而且没有字符串比较浪费的时间,也没有字符串拼接浪费的时间,故效果自然要好一些;
ps:官方给出的复杂度分析是有问题的,因为正常情况下每个结点的值都是各不相同的,那么就只需要执行一次完整的匹配算法就可以。