[路飞]_程序员必刷力扣题: 剑指 Offer 26. 树的子结构

108 阅读1分钟

剑指 Offer 26. 树的子结构

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

那么我们就先来查找与B树根节点的值一致的节点

  • 处理边界条件,A树或者B树如果都不存在的话,那就谈不上是否存在一致结构,直接返回false

  • 层序遍历A树,找到与B树根节点的值相等的节点,通过函数checkTree函数来比较,当前节点是否包含B树结构

  • checkTree的主要作用:对比参数一中是否包含参数二结构

因为要看是否包含B,而参数一的根节点完全等于B的根节点才执行此方法 所以直接以B树为主,进行遍历,如果B树拥有的每一个节点A树同样拥有则继续执行,中途有任何一个不同则返回false 如果顺利最后直接返回true

  • 因为A树中可能存在多个节点与B树的根节点的值相等;所以在isSubStructure函数中,当我们遇到与B节点一致的节点时,调用checkTree函数,如果返回true则成功,直接返回true,如果返回false,不代表立即失败,而是当前节点失败,继续往下遍历,如果全部遍历结束还没有返回true,则在末尾返回false
function checkTree(findB, B) {
    var stackB = [B]
    var stackFindB = [findB]
    while (stackB.length) {
        var item = stackB.shift()
        var itemFindB = stackFindB.shift()
        if (item.left) {
            if (itemFindB.left && item.left.val === itemFindB.left.val) {
                stackB.push(item.left)
                stackFindB.push(itemFindB.left)
            } else {
                return false
            }
        }

        if (item.right) {
            if (itemFindB.right && item.right.val === itemFindB.right.val) {
                stackB.push(item.right)
                stackFindB.push(itemFindB.right)
            } else {
                return false
            }
        }
    }

    return true
}
var isSubStructure = function (A, B) {
    if (!A || !B) return false
    var stack = [A]
    var findB
    while (stack.length) {
        var item = stack.shift()
        if (item.val === B.val) {
            findB = item
            var res = checkTree(findB, B)
            if (res) {
                return true
            }
        }
        if (item.left) { stack.push(item.left) }
        if (item.right) { stack.push(item.right) }
    }
    return false
};