• 剑指offer——树的子结构 (JAVA代码)


    版权声明:本文为博主原创文章,未经博主允许不得转载。

    题目描述

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

    解题思路:

      首先看牛客网给出的测试用例:

      

       一般对于树的操作不像链表一样,操作更复杂,如果使用循环遍历的话,对于非完全二叉树规律难寻,一般通用的方法就是使用递归求解,本题也不例外,同样使用递归求解,求解的大体思路是首先判断B的根节点和A的根节点是否相同(这里的相同是指节点的值相同并且左右子节点相同),如果相同比较他们的左右子节点,这一步骤是相同的,可以用递归完成,直到B遍历到每个尾节点,如果这一过程比较的所有节点是相同的,则证明B是A的子结构。如果B的根节点和A的根节点不同,则A向他的左右子节点滑动,然后继续跟B的子节点比较,步骤同上。

      递归的使用可以用我总结的三步来完成。求解过程如下:

      1. 递归截止条件。
      递归的截止条件是为了递归能够避免无限循环下去,首先来分析什么情况下递归截止返回遍历结果,(1)根据题目要求,如果B数是个空树,递归截止。(2)如果被遍历的树A是空树,自然而然递归截止。(3)如果比较的是B的尾节点,无法进行下去,递归也会截止。(4)如果A树从头遍历到尾始终没有和B的节点相同的节点,递归截止。
      2. 递归的前后衔接。
      如果A的根节点值以及左右子节点情况和B的根节点完全相同,那么A和B都继续滑动到他们的左右子节点进行比较;如果A的根节点值和B的根节点值是相同的,但是左右子节点的情况是不相同的,那么只滑动A到他的左右子节点再与B比较。如果A的根节点的值和B的根节点的值不相同,那么A直接滑动到他的左右自己点再和B的根节点比较,直到遍历完成。
      3. 递归节点数据的处理。
      根据题目,本题目中用到的递归并没有数据处理,只是比较判断两个树节点是否相同。对于其他递归,可以具体情况具体对待。

    源码:

     1     /**
     2      * 输入两棵二叉树A,B,判断B是不是A的子结构。
     3      * @param root1 A树
     4      * @param root2 B数
     5      * @return 
     6      */
     7     public static boolean HasSubtree(TreeNode root1,TreeNode root2) {
     8         
     9         if (root2==null) {        //空树不是任意一个树的子结构
    10             return false;
    11         }
    12         if (root1==null) {        //如果A为空,那肯定返回false
    13             return false;
    14         }
    15         if(root2.val==root1.val){        //A和B比较的根节点的值相同
    16             
    17             if (root2.left==null&&root2.right==null) {        //比较的节点是B的尾节点,递归截止
    18                 return true;
    19             }
    20             //下面三种比较的是比较的节点完全相同的情况
    21             if ((root2.left!=null&&root2.right!=null)&&(root1.left!=null&&root1.right!=null)&&root2.left.val==root1.left.val&&root2.right.val==root1.right.val) {
    22                 return HasSubtree(root1.left,root2.left)&& HasSubtree(root1.right,root2.right);
    23             }else if ((root2.left!=null&&root2.right==null)&&(root1.left!=null&&root1.right==null)&&root2.left.val==root1.left.val) {
    24                 return HasSubtree(root1.left,root2.left);
    25             }else if ((root2.left==null&&root2.right!=null)&&(root1.left==null&&root1.right!=null)&&root2.right.val==root1.right.val) {
    26                 return HasSubtree(root1.right,root2.right);
    27             }else{        //比较的节点不同,A向左右子节点移动一个再比较
    28                 if (root1.left!=null&&root1.right!=null) {
    29                     return  HasSubtree(root1.left,root2)|| HasSubtree(root1.right,root2);
    30                 }else if(root1.left==null&&root1.right!=null){
    31                     return  HasSubtree(root1.right,root2);
    32                 }else if(root1.left!=null&&root1.right==null){
    33                     return  HasSubtree(root1.left,root2);
    34                 }else {
    35                     return false;
    36                 }    
    37             }
    38         //比较的根节点的值不相同,直接向左右子节点滑动    
    39         }else if(root1.left!=null&&root1.right==null){
    40             return HasSubtree(root1.left,root2);
    41         }else if(root1.left==null&&root1.right!=null){
    42             return HasSubtree(root1.right,root2);
    43         }else{
    44             return false;
    45         }
    46     }
  • 相关阅读:
    快速排序
    09-HQL:Group、Order
    08-表属性操作
    07-数据导出及动态分区
    06-数据加载
    05-Hive数据操作
    04-表操作2
    03-表操作1
    [原创]IPV4分组的格式
    mysql中having和where的区别
  • 原文地址:https://www.cnblogs.com/centor/p/5803535.html
Copyright © 2020-2023  润新知