简单说一下思路:(千万别背,很好理解!)

1.HasSubtree——一般人都会想到的

首先人们大都能想到是去拿target树中的每个元素去和source树的每个元素去一一比对,方法是先判断root节点,然后再去左右子结点找,只要找到就行,没错!就是这样~

2.doesTree1HaveTree——打工人思维

然后我们为什么不能直接一次性在HasSubtree函数里面去调用HasSubtree来一步到位?问题就出在这里,你会发现,按照题目的理解,root节点只要为空,就一定返回false!然鹅,左、右节点却不这么认为,他们会说:我还没有成为老板节点(root)之前,甘愿做个隐形的打工人,可有可无。因此左右节点递归的逻辑稍稍不同,可以没有打工人( if(target == null) return true) , 但是不能没有老板(if(source == null) return false) 啊!并且你要按老板造好的轮子,一步一个脚印(亦步亦趋,脑子跟上,左脚右脚也跟上)地对着抄作业就行啦!

HasSubtree

/**
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 source, TreeNode target) {
        if (target == null || source == null) return false;
        return doesTree1HaveTree2(source, target) || 
            HasSubtree(source.left, target) || 
            HasSubtree(source.right, target);
    }

    public boolean doesTree1HaveTree(TreeNode source,TreeNode target){
        if(target == null) return true;
        if(source == null)  return false;
        return source.val == target.val && 
            doesTree1HaveTree2(source.left,target.left) && 
            doesTree1HaveTree2(source.right, target.right);
    }

}