【路飞】算法与数据结构-剑指 Offer 26. 树的子结构  

113 阅读2分钟

LeetCode:地址

题目要求

输入两棵二叉树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树 在A树找到节点值和B树的根节点值一样的节点 如果找不到就直接 return false; 第二步: 找到了之后就对比B是不是A的子树:如果不是就继续遍历A找下一个和B树的根节点值一样的节点值; 否则B是A的子树就可以return true了; 第三步: 树的遍历有4种情况: 1.左子树有,右子树有。 值不一样 return true; 否则 递归子树; 2.左子树无,右子树有。 return fasle; 2.左子树有,右子树无。 return true; 4.左子树无,右子树无。 return true;

代码
 * @param {TreeNode} A
 * @param {TreeNode} B
 * @return {boolean}
 */
var isSubStructure = function(A, B) {
    if(!B) return false;
    const valB = B.val;

    function dfs(node){
        if(!node) return false;
        // 如果节点值一样且B是子树 return true;
        if(node.val === valB && helper(node,B)) return true;
        return dfs(node.left) || dfs(node.right);
    }

    //判断B是不是A的子树
    function helper(nodeA,nodeB) {
        // 1.A的子树有,B的子树有。 如果值不一样 就直接return false; 否则递归子树
        if(nodeA && nodeB){
            if(nodeA.val !== nodeB.val) return false;
            return helper(nodeA.left,nodeB.left) && helper(nodeA.right,nodeB.right);
        }
        // 2.左子树无,右子树有。 return fasle;
        if(!nodeA && nodeB) return false;

        //3.左子树有,右子树无。 return true;
        //4.左子树无,右子树无。 return true;
        return true;
    }
    return dfs(A);
};