[路飞]_树的子结构

163 阅读2分钟

剑指 Offer 26. 树的子结构
b站视频

题目介绍

输入两棵二叉树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

解题思路

要解决这道题,需要利用两个递归函数来实现

首先,需要递归遍历 A 的节点,找到与 B 树的根节点的值相同的节点

1641658901(1).png 找到之后,需要遍历以这个节点为根节点的子树,比较 B 树的整个结构是不是在 A 树的这棵子树中

1641658930(1).png

动画过程

3.gif

解题代码

var isSubStructure = function(A, B) {
    // 如果 B 树是空树,或者遍历 A 树到了空节点,说明 B 树不在 A 树的子结构
    if (!A || !B) return false
    // 先判断 A 树的节点是不是等于 B 树的根节点
    // 如果不是,则递归判断 A 的左节点和右节点是不是 B 树的根节点
    return compare(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B)
};

var compare = function(A, B) {
    // 如果 B 树能够遍历完,说明 B 树在 A 树的子结构
    if (!B) return true
    // 如果 A 节点的值不等于 B 节点的值,说明,B 树不是当前 A 节点的子结构
    // 如果 A 树先遍历到空节点,说明 B 树存在 A 树不存在的节点
    if (!A || (A.val !== B.val)) return false
    // 如果 A 节点等于 B 节点,继续比较 A 的左节点和 B 的左节点,A 的右节点与 B 的右节点
    return compare(A.left, B.left) && compare(A.right, B.right)
}