剑指offer-树的子结构

 题目:树的子结构

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

思路:树类的题应该优先考虑用递归解,因为这样简单,理解递归也应该用树这种结构来理解,树这种结构好像天生就自带递归的特点

判断B树是不是A树的子结构,我只需要判断3处

1.B树与A树本身是否相等

2.B树与A树的左子树是否相等

3.B树 与A树的右子树是否相等

这是大的判断方向,具体落实到判断方法时,只需这样判断

1.递归这一层的B为null,直接返回true

2.递归这一层的A为Null,直接返回false

3.如果A,B的当前节点相同,返回判断A,B 树当前节点的左子树,右子树是否分别同时都相同

 

有不少人看不懂这里的1.递归这一层的B为null,直接返回true,他们认为既然题目要求约定空树不是任意一个树的子结构,那么为什么还要返回true,我觉得这是他们对递归过程缺乏一个形象的认识,这里的1.递归这一层的B为null,直接返回true 与2.递归这一层的A为Null,直接返回false 应该一起看,他是在讲在递归过程中A树完全包含B树,此时上面其他的节点A,B树都相等,B树到了最后一个叶节点的后面,那就说明B树在A树里,那自然要返回true,同理2.递归这一层的A为Null,直接返回false,A,B树的其他节点都已经相等了,,继续判断当前节点,发现我B树的所有节点都没判断完呢,你A树怎么在这里为空了,那么你A树在这里肯定是不能包含我B树的,所以返回fasle 

用个图来表示一下
1.递归这一层的B为null,直接返回true

  A       1                B    1
         / \ / \
         2 3 2 3
        / \ / \
       4 5 6 7
可以看出B到3后就已经完了,后面为空表明B树判断完了,所以自然返回true
2.递归这一层的A为Null,直接返回false


  A       1                B    1
         / \ / \
         2 null 2 3
        / \
       4 5

可以看出A中1的右节点为空,而此时B中1的右节点为3,那么此时A这里必然不能包含B,所以返回false,然后让递归转向下一层继续判断

代码;

 1 public class Solution {
 2     public boolean HasSubtree(TreeNode root1,TreeNode root2) {
 3         if(root2==null||root1==null)return false;
 4         return isSubtree(root1,root2)||HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);               
 5     }
 6     private boolean isSubtree(TreeNode root1,TreeNode root2){
 7         if(root2==null)return true;
 8         if(root1==null)return false;
 9         if(root1.val==root2.val){
10             return isSubtree( root1.left, root2.left)&&isSubtree( root1.right, root2.right);
11         }
12          else   return false;
13     }
14 }

 

posted @ 2018-06-06 11:09  pathjh  阅读(132)  评论(0编辑  收藏  举报