1 题目
Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself.
Example 1:
Given tree s:
3
/ \
4 5
/ \
1 2
Given tree t:
4
/ \
1 2
Return true, because t has the same structure and node values with a subtree of s.
Example 2:
Given tree s:
3
/ \
4 5
/ \
1 2
/
0
Given tree t:
4
/ \
1 2
2 尝试解
2.1 分析
要求给定两棵树,s和t,判断t是否为s的子树。
首先考虑空树的情况,如果s和t都为空,则是子树;如果有且仅有一个为空,则t不可能是s的子树。
如果s和t都不为空,判断s和t的值。如果s.val != t.val,则该问题变成t是否为s.left或s.right的子树。如果s.val == t.val, 此处需要注意,该问题不能转化为t.left是否为s.left的子树且t.right为s.right的子树。考虑如下情况,问题应该转化为s.left是否等同于t.left且s.right是否等同于t.right。所以需要一个辅助函数isSametree来判断是否为等同的树。
3 3
/ \ / \
4 5 1 5
/ \
1 2
2.2 代码
class Solution {
public:
bool sameTree(TreeNode* s, TreeNode* t){
if(!s && !t) return true;
if(!s || !t || s->val != t->val) return false;
return sameTree(s->left,t->left)&&sameTree(s->right,t->right);
}
bool isSubtree(TreeNode* s, TreeNode* t) {
if(!s && !t) return true;
if(!s || !t) return false;
if(s->val == t->val){
if(sameTree(s->left,t->left)&&sameTree(s->right,t->right))
return true;
}
return isSubtree(s->left,t) || isSubtree(s->right,t);
}
};
3 标准解
3.1 分析
在上述的基础上,还可以继续优化。可以计算出s中每棵子树的高度,并与t的高度进行比较,如果高度相同,再判断是否是相同的树。
3.2 代码
class Solution {
vector<TreeNode*> nodes;
public:
bool isSubtree(TreeNode* s, TreeNode* t) {
if (!s && !t) return true;
if (!s || !t) return false;
getDepth(s, getDepth(t, -1));
for (TreeNode* n: nodes)
if (identical(n, t))
return true;
return false;
}
int getDepth(TreeNode* r, int d) {
if (!r)
return -1;
int depth = max(getDepth(r->left, d), getDepth(r->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(r);
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);
}
};