记录 1 道算法题
树的子结构
剑指 Offer 26. 树的子结构 - 力扣(LeetCode) (leetcode-cn.com)
检查一个树是不是另一个树的子结构,就是某部分完全相同的意思,空树不是子结构。
首先先找到开头根节点匹配的地方,然后再逐个逐个往下对比。不对就返回 false。 分成两步操作。
isSubStructure 查询相同的开头根节点 hasSameNode 对节点进行比较
父(A):
a
b c
d
子(B):
b
d
第一次 isSubStructure() 比较 a ,b,不符合 false
第二次 isSubStructure() 比较 b , b, 符合 true
第一次 return false || true
function isSubStructure(A, B) {
// 其中一个为空就不用匹配了
if (!B || !A) return false
// 每次调用 isSubStructure 都会先调用 hasSameNode 检查节点,
// 所以判断逻辑写在 hasSameNode 里面
// 如果在开头就匹配上的话,就不会再递归 isSubStructure 了
return hasSameNode(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B)
}
function hasSameNode(A, B) {
// 内部还会再进行递归
// 当 B 先被消耗完的时候,可以认定节点一直都匹配得上
if (!B) return true
// 如果出现了不相等
if (!A || A.val !== B.val) {
return false
} else {
// 相等就继续检查子节点,一定都是 true 才算结构相等。
return hasSameNode(A.left, B.left) && hasSameNode(A.right, B.right)
}
}
isSubStructure 和 hasSameNode 的关系就像是 isSubStructure 负责找 B 固定时的A的情况, hasSameNode 负责找 B 的开头和 A 匹配上的时候,他们的 left 和 right 是否一致,是 A 更长一点 还是 B 更长一点。如果是 A 的话,就代表遍历完 B 的时候, A 还有剩余节点。 如果是 B 的话,就代表 A 遍历完时, B 还有剩余节点没匹配,就直接不符合了。