###### tags: `LeetCode` `Tree` `Easy` `Recursion`
# LeetCode #572 [Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/)
### (Easy)
給你兩棵二元樹 root 和 subRoot 。檢驗 root 中是否包含和 subRoot 具有相同結構和節點值的子樹。如果存在,返回 true ;否則,返回 false 。
二元樹 tree 的一棵子樹包括 tree 的某個節點和這個節點的所有後代節點。 tree 也可以看做它自身的一棵子樹。
---
與 #100 Same Tree類似, 寫一函式確認是否是相同樹, 接著回傳root與subRoot的相同樹比對或是root->left與subRoot, root->right與subRoot的子樹比對即可。時間複雜的O(n)。
```
class Solution {
public:
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
return subtree(root, subRoot);
}
bool issame(TreeNode* node1, TreeNode* node2){
if(!node1&&!node2)return true;
else if((!node1&&node2)||(node1&&!node2))return false;
else if(node1&&node2)return (node1->val==node2->val)&&issame(node1->left,node2->left)&&issame(node1->right,node2->right);
return false;
}
bool subtree(TreeNode* root, TreeNode* node){
if(!root)return false;
else if(root->val==node->val)return issame(root, node)||subtree(root->left, node)||subtree(root->right, node);
else return subtree(root->left, node)||subtree(root->right, node);
}
};
```
---
LeetCode上更快的寫法(線性時間)
root為主要樹, subRoot為比較樹, 確認subRoot是否為root的子樹。
getDepth函式負責確認節點高度, 首先先呼叫getDepth(subRoot,-1)得到subTree的高度, 代表在比較樹高時, 只有在該高度的樹有可能符合條件成為子樹。
接下來呼叫getDepth(root,getDepth(subRoot,-1)), 代表找到root樹中高度為getDepth(subRoot,-1)的節點, 只有高度符合的節點能成為比對子樹的候選者。
將符合的節點放入數組中,並一一進行sametree比對, 這樣省去了遞迴的時間,時間複雜度為O(n)。
```
class Solution {
vector<TreeNode*> nodes;
public:
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
if (!root && !subRoot) return true;
if (!root || !subRoot) return false;
getDepth(root, getDepth(subRoot, -1));
for (TreeNode* n: nodes){
if (identical(n, subRoot))
return true;
}
return false;
}
int getDepth(TreeNode* node, int d) {
if (!node)
return -1;
int depth = max(getDepth(node->left, d), getDepth(node->right, d)) + 1;
// Check if depth equals required value
// Require depth is -1 for tree t (only return the depth, no push)
if (depth == d)
nodes.push_back(node);
return depth;
}
bool identical(TreeNode* a, TreeNode* b) {
if (!a && !b) return true;
if (!a || !b || a->val != b->val) return false;
return identical(a->left, b->left) && identical(a->right, b->right);
}
};
```