题目描述

image.png
其他相同题型可以参照🔗

解题思路

recur(A, B) 函数:
终止条件:

  • 当节点 B 为空:说明树 B 已匹配完成(越过叶子节点),因此返回 true ;
  • 当节点 A 为空:说明已经越过树 A 的叶节点,即匹配失败,返回 false ;
  • 当节点 A 和 B 的值不同:说明匹配失败,返回 false ;

返回值:

  • 判断 A 和 B 的 左子节点 是否相等,即 recur(A.left, B.left) ;
  • 判断 A 和 B 的 右子节点 是否相等,即 recur(A.right, B.right) ;

isSubStructure(A, B) 函数:

  • 特例处理: 当 树 A 为空 或 树 B 为空 时,直接返回 false ;
  • 返回值: 若树 B 是树 A 的子结构,则必满足以下三种情况之一,因此用或 || 连接;
    • 以 节点 A 为根节点的子树 包含树 B ,对应 recur(A, B);
    • 树 B 是 树 A 左子树 的子结构,对应 isSubStructure(A.left, B);
    • 树 B 是 树 A 右子树 的子结构,对应 isSubStructure(A.right, B);

此题需要判断的是子树,而不是从根节点开始,所以相当于需要深度遍历数A,再从树A的每个节点进行比较判断.

  1. class Solution {
  2. public boolean isSubStructure(TreeNode A, TreeNode B) {
  3. return (A !=null && B != null) && (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B));
  4. }
  5. public boolean recur(TreeNode A, TreeNode B) {
  6. if (B == null) return true;
  7. else if (A == null || A.val != B.val) return false;
  8. else return recur(A.left, B.left) && recur(A.right, B.right);
  9. }
  10. }
  • 时间复杂度 O(MN) : 其中 M,N 分别为树 A 和 树 B 的节点数量;先序遍历树 A 占用 O(M) ,每次调用 recur(A, B) 判断占用 O(N) 。
  • 空间复杂度 O(M) : 当树 A 和树 B 都退化为链表时,递归调用深度最大。当 M≤N 时,遍历树 A 与递归判断的总递归深度为 M ;当 M>N 时,最差情况为遍历至树 A 的叶节点,此时总递归深度为 M。