数的子结构


题目内容

至于什么叫做数的子结构、子树,请参考该文 二叉树的子树、子结构

尝试一

结果:失败

/**
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(root2==null || root1==null){
            return false;
        }
        
        return isSubtree(root1,root2);
       
        
    }
    
    private boolean isSubtree(TreeNode a,TreeNode b){
        if(b==null){//说明b已经被遍历完了
            return true;
        }
         if(b.val!=a.val){//换个节点
             return false;
             isSubtree(a.left,b);
             isSubtree(a.right,b);
        }
        if(isSubtree(a.left,b.left)){
            return isSubtree(a.right,b.right);
        }
        
        return false;
    }
}

测试:

不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为0.00%

用例:
{8,8,7,9,2,#,#,#,#,4,7},{8,9,2}

对应输出应该为:

true

你的输出为:

java.lang.NullPointerException

在这里插入图片描述
问题在于:当左边的第一个8和右边的第一个8比较成功之后,比较左边的第二个8与右边的9,此时不匹配,左边左移。问题就是这里。

尝试二

结果:部分通过(55%)

/**
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(root2==null || root1==null){
            return false;
        }
       
        
        return iterator(root1,root2);
       
        
    }
    
    private boolean iterator(TreeNode a,TreeNode root2){
        if(a==null){
            return false;
        }
        
        //这句话只是打印出值而已,看处理到哪里了
        System.out.println(a.val);
        /*找到之后就返回*/
        if(isSubtree(a,root2))
        {
            return true;
        }
        if(iterator(a.left,root2)==false){
            return  iterator(a.right,root2);
        }
       
        return true;
    }
    
    private boolean isSubtree(TreeNode a,TreeNode b){
        if(b==null){//说明b已经被遍历完了
            return true;
        }
        if(b.val!=a.val){//换个节点
             return false;
        }
        if(isSubtree(a.left,b.left)){
            return isSubtree(a.right,b.right);
        }
        
        return false;
    }
}

思路:先遍历A树,然后对a树每个节点依次在递归判断是否与B树的节点一样。也就是递归遍历A树的递归中,再用递归判断是否与B树一样。

测试用例:

不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为55.56%

用例:
{8,#,8,#,9,#,2,#,5},{8,#,9,3,2}

对应输出应该为:

false

你的输出为:

java.lang.NullPointerException

分析:
在这里插入图片描述
当出现上图情况时,就炸了。因为存在null

尝试三

结果:通过

/**
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(root2==null || root1==null){
            return false;
        }
       
        
        return iterator(root1,root2);
       
        
    }
    
    private boolean iterator(TreeNode a,TreeNode root2){
        if(a==null){
            return false;
        }
        
        //这句话只是打印出值而已,看处理到哪里了
        System.out.println(a.val);
        /*找到之后就返回*/
        if(isSubtree(a,root2))
        {
            return true;
        }
        if(iterator(a.left,root2)==false){
            return  iterator(a.right,root2);
        }
       
        return true;
    }
    
    private boolean isSubtree(TreeNode a,TreeNode b){
        if(b==null){//说明b已经被遍历完了
            return true;
        }
        /*b有左或右节点时,而a没有对应的左右节点,递归结束*/
        if(a==null){
            return false;
        }
        if(b.val!=a.val){//换个节点
             return false;
        }
        if(isSubtree(a.left,b.left)){
            return isSubtree(a.right,b.right);
        }
        
        return false;
    }
}

我在尝试二的isSubtree中加了下面代码:

  /*b有左或右节点时,而a没有对应的左右节点,递归结束*/
        if(a==null){
            return false;
        }

结论

  • 递归里面套递归,这还是第一次。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值