题目描述 另一个树的子树
给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
示例
给定的树 s:
3
/ \
4 5
/ \
1 2
给定的树 t:
4
/ \
1 2
返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。
错误思路
本来想的是先遍历s,找到第一个与t相同的TreeNode,然后判断是否此时的两部分是否一致
代码
class Solution {
public:
bool sameTree(TreeNode* s, TreeNode* t)
{
if(s == NULL && t == NULL) return true;
if(s == NULL) return false;
if(t == NULL) return false;
if(s->val != t->val) return false;
return sameTree(s->left, t->left) && sameTree(s->right, t->right);
}
bool isSubtree(TreeNode* s, TreeNode* t) {
queue<TreeNode*> temp;
temp.push(s);
while(!temp.empty())
{
TreeNode* q;
q = temp.front();
if(q->val == t->val)
{
return sameTree(q, t);
}
else
{
if(q->left != NULL)
{
temp.push(q->left);
}
if(q->right != NULL)
{
temp.push(q->right);
}
temp.pop();
}
}
return false;
}
};
但这种思路是不对的
报错
正确思路
事实证明,是自己蠢得离谱,判断一个树是否是另一个树的子树,一共有三种情况
- s与t完全相同
- t是s的左树的子树
- t是s的右树的子树
这样理解起来就很容易了
代码
class Solution {
public:
bool sameTree(TreeNode* s, TreeNode* t)
{
if(s == NULL && t == NULL) return true;
if(s == NULL) return false;
if(t == NULL) return false;
if(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 == NULL && t == NULL) return true;
if(s == NULL && t!= NULL) return false;
return sameTree(s, t) || isSubtree(s->left, t) || isSubtree(s->right, t);
}
};
性能分析
对于一个深度较深的树,采用递归去求解使得性能较差