算法14.树的子结构


题目描述

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

示例 1:

给定的树 A:

     3
    / \
   4   5
  / \
 1   2
给定的树 B:
   4 
  /
 1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

示例 2:

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

解题思路

方法一:普通分析

时间复杂度:$O(MN)$

空间复杂度:$O(M)$

代码如下

class Solution {
public:
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        if(A==NULL || B==NULL) return false;
        if(A->val == B->val) return reverse(A,B) || isSubStructure(A->left,B) || isSubStructure(A->right,B);
        if(A->val != B->val) return isSubStructure(A->left,B) || isSubStructure(A->right,B);
        return false;
    }
    bool reverse(TreeNode *A,TreeNode *B){
        if(B==NULL) return true;
        if(A==NULL || A->val!=B->val)   return false;
        return reverse(A->left,B->left) && reverse(A->right,B->right);
    }
};

解法分析

要找到匹配的子树,首先头结点需要首先匹配。所以需要遍历$A$子树,寻找头结点匹配的子树。

需要找合适的头结点之后,接着对该头结点下面形成的树和$B$子树进行匹配。双重递归!

匹配过程是在$reverse$函数中进行,具体如下:

终止条件
当节点 $B$ 为空:说明树 $B$ 已匹配完成(越过叶子节点),因此返回 $true$ ;
当节点 $A$ 为空:说明已经越过树 $A$ 叶子节点,即匹配失败,返回 $false$ ;
当节点 $A$ 和 $B$ 的值不同:说明匹配失败,返回 $false$ ;
返回值
判断 $A$ 和 $B$ 的左子节点是否相等,即 $recur(A.left, B.left)$ ;
判断 $A$ 和 $B$ 的右子节点是否相等,即 $recur(A.right, B.right)$ ;

而主函数的返回值必须满足以下三种情况之一:

  1. 以 节点 $A$ 为根节点的子树 包含树 $B$ ,对应 $recur(A, B)$;
  2. 树 $B$ 是 树 $A$ 左子树 的子结构,对应 $isSubStructure(A.left, B)$;
  3. 树 $B$ 是 树 $A$ 右子树 的子结构,对应 $isSubStructure(A.right, B)$;

文章作者: ray
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ray !
评论
 上一篇
算法15.对称的二叉树 算法15.对称的二叉树
题目描述请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。 示例 1: 二叉树 [1,2,2,3,4,4,3] 是对称的。 1 / \ 2 2 / \ / \ 3 4 4
2020-10-27
下一篇 
算法13.反转链表 算法13.反转链表
题目描述定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。 示例 1: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 解题思路方法一:普通分析 时间复杂度:$O(N)
2020-10-19
  目录