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 scould 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
Return false.
这道题让我们求一个数是否是另一个树的子树,从题目中的第二个例子中可以看出,子树必须是从叶结点开始的,中间某个部分的不能算是子树,那么我们转换一下思路,是不是从s的某个结点开始,跟t的所有结构都一样,那么问题就转换成了判断两棵树是否相同,也就是Same Tree的问题了,这点想通了其实代码就很好写了,用递归来写十分的简洁,我们先从s的根结点开始,跟t比较,如果两棵树完全相同,那么返回true,否则就分别对s的左子结点和右子结点调用递归再次来判断是否相同,只要有一个返回true了,就表示可以找得到。
解法一:
class Solution {
public:
bool isSubtree(TreeNode* s, TreeNode* t) {
if (!s) return false;
if (isSame(s, t)) return true;
return isSubtree(s->left, t) || isSubtree(s->right, t);
}
bool isSame(TreeNode* s, TreeNode* t) {
if (!s && !t) return true;
if (!s || !t) return false;
if (s->val != t->val) return false;
return isSame(s->left, t->left) && isSame(s->right, t->right);
}
};
下面这道题的解法用到了之前那道Serialize and Deserialize Binary Tree的解法,思路是对s和t两棵树分别进行序列化,各生成一个字符串,如果t的字符串是s的子串的话,就说明t是s的子树,但是需要注意的是,为了避免出现[12], [2], 这种情况,虽然2也是12的子串,但是[2]却不是[12]的子树,所以我们再序列化的时候要特殊处理一下,就是在每个结点值前面都加上一个字符,比如’,’,来分隔开,那么[12]序列化后就是”,12,#”,而[2]序列化之后就是”,2,#”,这样就可以完美的解决之前的问题了,参见代码如下:
解法二:
class Solution {
public:
bool isSubtree(TreeNode* s, TreeNode* t) {
ostringstream os1, os2;
serialize(s, os1);
serialize(t, os2);
return os1.str().find(os2.str()) != string::npos;
}
void serialize(TreeNode* node, ostringstream& os) {
if (!node) os << ",#";
else {
os << "," << node->val;
serialize(node->left, os);
serialize(node->right, os);
}
}
};
类似题目:
Serialize and Deserialize Binary Tree
参考资料:
https://discuss.leetcode.com/topic/88508/java-solution-tree-traversal
https://discuss.leetcode.com/topic/88491/java-concise-o-n-m-time-o-n-m-space
https://discuss.leetcode.com/topic/88700/easy-o-n-java-solution-using-inorder-and-preorder-traversal
LeetCode All in One 题目讲解汇总(持续更新中…)
转载请注明来源于 Grandyang 的博客 (grandyang.com),欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 grandyang@qq.com