[Leetcode]树的子结构
February 04, 2021
1688
[剑指offer26] 树的子结构
[TOC]
题目
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
例如:
给定的树 A:3
/ \4 5
/ \
1 2
给定的树 B:4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。示例 1:
输入:A = [1,2,3], B = [3,1]
输出:false
示例 2:输入:A = [3,4,5,1,2], B = [4,1]
输出:true
限制:0 <= 节点个数 <= 10000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
如果B 是树 A 的子结构,则子结构的根节点可能是树 A 上的任意一个节点。所以判断B是不是树A的子结构,需要完成以下两步工作:
先序遍历树
A上的每个节点 Ai (对应的函数isSubStructure(A, B))判断树
A上 以Ai为根节点的子树是否包含树B(对应函数recur(A, B))
算法流程
recur(A, B)函数:
- 终止条件:
- 当节点B为空时,说明树B 已经匹配完成了,返回
true; - 当节点A为空时,说明树B的节点已经超越了树A 的节点,即匹配失败,返回false;
- 当节点A和B的值不同时,说明不是子树,返回false;
- 当节点B为空时,说明树B 已经匹配完成了,返回
- 返回值:
- 判断A 和 B的左节点是否相等,即
recur(A.left, B.left); - 判断 A 和 B 的右子节点是否相等,即
recur(A.right, B.right);
- 判断A 和 B的左节点是否相等,即
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 为根节点的子树包含树B
复杂度分析
- 时间复杂度 $\ 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。
代码
1 | |
- 本文作者:Jun
- 本文链接:http://mambajun.github.io/2021/02/04/Leetcode-%E6%A0%91%E7%9A%84%E5%AD%90%E7%BB%93%E6%9E%84/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!