🚩传送门:力扣题目

题目

输入两棵二叉树[LC]26. 树的子结构 - 图1[LC]26. 树的子结构 - 图2,判断[LC]26. 树的子结构 - 图3是不是[LC]26. 树的子结构 - 图4的子结构。(约定空树不是任意一个树的子结构)
[LC]26. 树的子结构 - 图5[LC]26. 树的子结构 - 图6的子结构, 即 [LC]26. 树的子结构 - 图7中有出现和[LC]26. 树的子结构 - 图8相同的结构和节点值。

例如下图所示就是一个子结构
[LC]26. 树的子结构 - 图9
示例 1:

输入:A = [1,2,3], B = [3,1] 输出:false

示例 2:

输入:A = [3,4,5,1,2], B = [4,1] 输出:true

解题思路:递归

若树[LC]26. 树的子结构 - 图10是树[LC]26. 树的子结构 - 图11的子结构,则子结构的根节点可能为树[LC]26. 树的子结构 - 图12的任意一个节点。因此,判断树[LC]26. 树的子结构 - 图13是否是树[LC]26. 树的子结构 - 图14的子结构,需完成以下两步工作:

  1. 先序遍历树[LC]26. 树的子结构 - 图15中的每个节点 [LC]26. 树的子结构 - 图16;(对应函数 [LC]26. 树的子结构 - 图17
  2. 判断树[LC]26. 树的子结构 - 图18 中以节点 [LC]26. 树的子结构 - 图19的为根的子树中是否包含树[LC]26. 树的子结构 - 图20

[LC]26. 树的子结构 - 图21

复杂度分析

时间复杂度:[LC]26. 树的子结构 - 图22,其中 [LC]26. 树的子结构 - 图23 , [LC]26. 树的子结构 - 图24 分别是树[LC]26. 树的子结构 - 图25和树[LC]26. 树的子结构 - 图26的节点数量

空间复杂度:[LC]26. 树的子结构 - 图27, 当树[LC]26. 树的子结构 - 图28和树[LC]26. 树的子结构 - 图29都退化为链表时,递归调用深度最大。

我的代码

  1. class Solution {
  2. public boolean isSubStructure(TreeNode A, TreeNode B) {
  3. if (B == null) return false; // 约定空树不是任意一个树的子结构
  4. if (A == null) return false; // B非空,A空一定不可能匹配
  5. // A为根的子结构 || A左子树中的子结构 || A右子树中的子结构
  6. return (isMatching(A, B)) || isSubStructure(A.left, B) || isSubStructure(A.right, B);
  7. }
  8. private boolean isMatching(TreeNode A, TreeNode B) {
  9. // B 空匹配完成
  10. if (B == null) return true;
  11. // B 非空 A 空了说明不能匹配
  12. if (A == null) return false;
  13. // 均非空时,根值相等,且左右子树匹配
  14. return A.val == B.val && isMatching(A.left, B.left) && isMatching(A.right, B.right);
  15. }
  16. }