剑指 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
};