《剑指Offer》Java刷题 NO.17 树的子结构

《剑指Offer》Java刷题 NO.17 树的子结构(二叉树、递归、短路特点)

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


先搞清楚子树和子结构的的区别: 子树的意思是只要包含了一个结点,就得包含这个结点下的所有节点. 子结构的意思是至少包含一个结点就可以 简单而言,与子树不同的是,子结构可以是A树的任意一部分。 以下示意图A子树的用红框标注的都是它的子树,蓝框标注的是其中一个子结构 思路: 利用递归以及短路特点

  1. 判断B是A的子结构还是A的左子树的子结构还是A的右子树的子结构,都不是的话就返回false
  2. 如上图所示,先判断两棵树根结点的值是否相同
  3. 如果不同,就继续递归往下找,比较A的左子树和右子树有无结点的值结点的值是否和B的根结点的值相等
  4. 直到找到相等的结点,再递归判断B树的左子树和右子树是否同时是A的子结构,判断原则:
    先判断B树,如果B树先到了null(包含AB同时到底的情况),那么B肯定是A的子结构; 如果A树先到了null,那么B肯定是A的子结构; 如果B有某个结点的值和A的对应结点的值不相等,B也不是A的子结构 如果找不到相等的结点,B也不是A的子结构

Java代码:

class TreeNode {
          
   
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
          
   
        val = x;
    }

    TreeNode() {
          
   

    }
}
/**
 * 输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
 */
public class HasSubTree {
          
   
    public static boolean hasSubTree(TreeNode root1,TreeNode root2){
          
   
        if(root1==null||root2==null) return false;//空树不是任意一个树的子结构
        return isBigTreeSub(root1,root2)||hasSubTree(root1.left,root2)||hasSubTree(root1.right,root2);
        //短路特点:如果tree2是当前大树的子结构就不用进行后面的程序了
        //否则就判断tree2是不是当前大树的左子树的子结构..否则..右...
    }
    /**
     * 子函数:判断root2是不是以当前root1为根结点的大树的子结构
     * 两者根结点相等的话,就判断tree2的左子树和右子树是否同时满足是tree1的左、右子树的子结构
     * 否则就不是其子结构
     */

    public static boolean isBigTreeSub(TreeNode root1,TreeNode root2){
          
   
        if(root2==null) return true;//初始时root1和root2都不是null,只有递归时才会出现root2==null
        //而此情况(tree2先到达终点)包含root1==null和root1!=null两种情况,都应该返回true;
        //反之如果先判断root1==null时,root2==null和root2!=null两种情况返回值不相同
        if(root1==null) return false;//tree1先到达终点
        if(root1.val==root2.val)
            //找到相同的结点了!!开始看tree2的左子树和右子树是不是同时满足是tree2的左右子树的子结构
            return isBigTreeSub(root1.left,root2.left)&&isBigTreeSub(root1.right,root2.right);
            //短路特点:只要tree2的左子树不是tree1的左子树的子结构,就不用判断右子树了
        else return false;
    }
}
经验分享 程序员 微信小程序 职场和发展