简单说一下思路:(千万别背,很好理解!)
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);
}
}