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);
}
}
};

类似题目:

Count Univalue Subtrees

Most Frequent Subtree Sum

Serialize and Deserialize Binary Tree

Same 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 题目讲解汇总(持续更新中...)

[LeetCode] Subtree of Another Tree 另一个树的子树的更多相关文章

  1. 第26题:LeetCode572:Subtree of Another Tree另一个树的子树

    题目描述 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树.s 的一个子树包括 s 的一个节点和这个节点的所有子孙.s 也可以看做它自身的一棵子树. 示例 1: ...

  2. Leetcode572.Subtree of Another Tree另一个树的子树

    给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树.s 的一个子树包括 s 的一个节点和这个节点的所有子孙.s 也可以看做它自身的一棵子树. 示例 1: 给定的树 ...

  3. LeetCode 572. 另一个树的子树(Subtree of Another Tree) 40

    572. 另一个树的子树 572. Subtree of Another Tree 题目描述 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树.s 的一个子树包括 ...

  4. [程序员代码面试指南]二叉树问题-判断t1树是否包含t2树的全部拓扑结构、[LeetCode]572. 另一个树的子树

    题目1 解 先序遍历树1,判断树1以每个节点为根的子树是否包含树2的拓扑结构. 时间复杂度:O(M*N) 注意区分判断总体包含关系.和判断子树是否包含树2的函数. 代码 public class Ma ...

  5. LeetCode 572. 另一个树的子树

    题目链接:https://leetcode-cn.com/problems/subtree-of-another-tree/ 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和 ...

  6. LeetCode 572. 另一个树的子树 | Python

    572. 另一个树的子树 题目来源:https://leetcode-cn.com/problems/subtree-of-another-tree 题目 给定两个非空二叉树 s 和 t,检验 s 中 ...

  7. Java实现 LeetCode 572 另一个树的子树(遍历树)

    572. 另一个树的子树 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树.s 的一个子树包括 s 的一个节点和这个节点的所有子孙.s 也可以看做它自身的一棵子树 ...

  8. 力扣Leetcode 572. 另一个树的子树

    另一个树的子树 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树.s 的一个子树包括 s 的一个节点和这个节点的所有子孙.s 也可以看做它自身的一棵子树. 示例 ...

  9. 【LeetCode】572. 另一个树的子树 Subtree of Another Tree(Python & Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:先序遍历 方法二:DFS + DFS 方法三 ...

随机推荐

  1. linux dd使用记录

    dd if=/dev/sda of=/dev/sdb bs=10M Linux下显示dd命令的进度: dd if=/dev/zero of=/tmp/zero.img bs=10M count=100 ...

  2. 20162320刘先润第三周Bag类测试

    前言 以下内容是本周Bag代码的课后作业,要求是完成伪代码.产品代码和测试代码,为了书写方便我将伪代码以注释的形式写在了产品代码的后面 测试步骤 1.首先对Bag类引用BagInterface的代码进 ...

  3. 201621123060《JAVA程序设计》第十一周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...

  4. 201621123035 《Java程序设计》第1周学习总结

    1.本周学习总结 本周学习内容:Java平台概论.认识JDK规范与操作.了解JVM.JRE与JDK.撰写Java原始码.path是什么 关键词:JVM.JRE.JDK 联系:JVM是Java虚拟机的缩 ...

  5. 作业07-Java GUI编程

    1. 本周学习总结 1.1 思维导图:Java图形界面总结 1.2 可选:使用常规方法总结其他上课内容. 关于事件.事件源.事件监听器的总结: 事件:用户在GUI上进行的操作,如鼠标单击.输入文字.关 ...

  6. DistBlockNet:A Distributed Blockchains-Based Secure SDN Architecture for IOT Network

    现有问题 随着IOT中智能设备多样性和数目的增加,IOT的灵活性,效率,可用性,安全性和可扩展性的问题越来越明显. 实验目标 按照高适应性,可用性,容错性,性能,可靠性,可扩展性和安全性的设计原则,构 ...

  7. Struts2之Action的实现

    对于Struts2框架来说,最重要的莫过于Action类的编写,类比于Servlet,Action类也是通过类的实例对象调用方法来处理请求的,Action类的实例对象是由Struts2的核心Filte ...

  8. Hibernate与mysql的对应类型

    Hibernate映射类型 Java类型 标准SQL类型  integer  java.lang.Integer  integer  long  java.lang.Long  bigint  sho ...

  9. a标签传递参数

    a标签传递参数 单个参数:参数名称前面跟   ? <a href="localhost:8080/arguments?id=1">单个参数</a> 多个参数 ...

  10. System.Reflection名称空间下的程序集类Assembly应用.

    利用反射中的程序集类(Assembly--抽象类)动态加载类库(.dll)或者可执行程序(.exe). 优点:①.可以消除if条件的逻辑判断.②.减少内存资源.③.有利于程序扩展. 缺点... 使用静 ...