剑指Offer—树的子结构

树的子结构

题目

解题思路一:递归方式,依次把根节点、做孩子节点、有孩子节点作为根节点递归判断,只要有一个返回为true则就是子结构。判断的过程也是递归的,先判断根节点、左孩子是否一样,再判断右孩子。

public boolean HasSubtree(TreeNode root1,TreeNode root2) {
    //如果root1和root2都为空则直接返回false
    if (root1==null||root2==null) return false;
    //判断是否是子结构
    return judeg(root1,root2);
}

public boolean judeg(TreeNode root1,TreeNode root2){
    //如果root1和root2都为空则直接返回false
    if (root1==null||root2==null) return false;
    //先判断根节点
    boolean b = isSubtree(root1, root2);
    if (!b){
        //根节点不是就递归让左孩子为根节点
        b = judeg(root1.left, root2);
        if (!b){
            //根节点和做孩子作为根都不是则递归让有孩子作为根
            b = judeg(root1.right, root2);
        }
    }
    //返回判断结果
    return b;
}
private boolean isSubtree(TreeNode root1, TreeNode root2) {
    //如果root2遍历完了都能对应上,返回true
    if (root2==null) return true;
    //如果root2遍历完了,root1还没遍历完,返回false
    if (root1==null) return false;
    //如果有一个节点没有对上返回fasle
    if (root1.val!=root2.val) return false;
    //如果根节点对上了,则分别去子节点里面匹配
    return isSubtree(root1.left,root2.left)&&isSubtree(root1.right,root2.right);
}

解题思路二:字符串比较,第一种方式判断比较麻烦,我们直接把root1和root2转换为字符串进行比较,如果root2是root1的子结构,则root2的字符串一定包含在root1对应的字符串里面。

/**
 * 字符串比较的方式
 * @param root1
 * @param root2
 * @return
 */
public boolean HasSubtree2(TreeNode root1,TreeNode root2) {
    if(root2 == null || root1 == null){
        return false;
    }
    StringBuffer root1Str = new StringBuffer();
    StringBuffer root2Str = new StringBuffer();
    visitTree(root1,root1Str);
    visitTree(root2,root2Str);
    if(root1Str.indexOf(root2Str.toString()) > 0){
        return true;
    }
    return false;
}

/**
 * 转化为字符串
 * @param root
 * @param buffer
 */
private void visitTree(TreeNode root,StringBuffer buffer){
    if(root!=null){
        buffer.append(root.val);
        visitTree(root.left,buffer);
        visitTree(root.right,buffer);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值