在當前二叉樹中查詢指定子樹(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:官方給出的複雜度分析是有問題的,因爲正常情況下每個結點的值都是各不相同的,那麼就只需要執行一次完整的匹配算法就可以。