JZ17 树的子结构

JZ17 树的子结构

描述

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

示例

输入:

{8,8,#,9,#,2,#,5},{8,9,#,2}

返回值:

true

解析

这题的思路还是比较明确的,树的问题基本都涉及到树的遍历,此处要遍历树 A,寻找与树 B 根节点相同的节点,从这个相同节点开始判断是否为子结构。

一开始写的代码为

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root1 == null || root2 == null)
            return false;
        // 遍历树 A 的同时判断节点是否相同
        return IsSubTree(root1,root2) || HasSubtree(root1.left,root2) || HasSubtree(root1.right,root2);
    }
    
    // 判断是否为子树
    public boolean IsSubTree(TreeNode node1,TreeNode node2){
        // 若两个节点都为空,也是相同的
        if(node1 == null && node2 == null )
            return true;
        // 只有一个节点为空,说明肯定不一样
        if(node1 == null || node2 == null)
            return false;
        // 两节点不一样返回 false
        if(node1.val != node2.val )
            return false;
        // 递归判断左右子树
        return IsSubTree(node1.left,node2.left) && IsSubTree(node1.right,node2.right);
    }
    
}

提交结果为9/14 组用例通过,出现了问题

用例输出:

{8,8,7,9,2,#,#,#,#,4,7},{8,9,2}

预期输出:

true

实际输出:

false

问题出在哪呢?看一看树 A 和树 B 的结构

JZ17 树的子结构

可以发现,树 B 确实是 树 A 的子结构,但不是树 A 的子树!在判断到节点 2 的时候,树 A 的节点 2 有左右孩子 4 和 7,而树 B 的节点 2 没有左右孩子。上面的代码判断的是否为子树,所以产生了错误。

修改后的代码

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root1 == null || root2 == null)
            return false;
        // 遍历树 A 的同时判断节点是否相同
        return IsSubTree(root1,root2) || HasSubtree(root1.left,root2) || HasSubtree(root1.right,root2);
    }
    
    // 判断是否为子结构
    public boolean IsSubTree(TreeNode node1,TreeNode node2){ 
        // 树 B 没有的节点,对树 A 不用做判断
        if( node2 == null )
            return true;
        // 树 B 有但树 A 没有的节点,说明不一样了
        if( node1 == null )
            return false;
        // 两节点不一样返回 false
        if(node1.val != node2.val )
            return false;
        // 递归判断左右子树
        return IsSubTree(node1.left,node2.left) && IsSubTree(node1.right,node2.right);
    }
}

用例全部通过!

总结

还是那句话:树的问题基本都会涉及树的遍历。在这题中要注意区分子树和子结构的概念!

上一篇:【杂谈】没有公网IP的电脑如何与外部通信


下一篇:java-断开HttpClient的连接