题目:给两个树A和B,判断A是不是包含B(B是不是A的子结构),规定null不是子结构。
public boolean isSubStructure(TreeNode A, TreeNode B)
思路:树的解法一般是递归方法。
-
首先isSubStructure这个是个递归方法,不断拿A的left和right和B作匹配。(要考虑null不是子结构)然后判断以A和B为根节点的两个树是不是包含关系还需要一个方法judge,它也是一个递归方法。
-
有帮助的是拿例子去跑一跑,然后改例子的节点,加一个节点或者该一个节点的值。可以看的更全面。
-
什么时候算A包含B(judge返回ture)?当然是B遍历完了,A遍历完了没有都可以。那B遍历完了的标志就是B为null。所以当B为null一定是返回true的。那跑例子时发现有A和B同时为null的情况,由于先判定B==null,也就正好符合跳过了(也返回true,因为A和B都为null表示到了叶子节点,跳过就好)。
-
那跑例子还会发现A提前为null(而B不为null),这说明B中有的A中没有(A不包含B),所以返回false。同理A这个节点存在,但是值不与B的相等,所以也返回false。
-
最后A.left和B.left,A.right和B.right继续向下就行了。
/*
可以拿给的例子去跑一跑,然后自己改例子,比如多加一个节点,改一个节点的值
这样能更全面地去分析问题。
*/
public boolean isSubStructure(TreeNode A, TreeNode B) {
/*
A和B节点有一个为null就返回false(null不是子结构,而且A为null也包含不了B)
然后递归拿A的left和right和B配对,judge是根节点A和B配对的细节实现
*/
return (A != null && B != null) && (judge(A,B)
|| isSubStructure(A.left,B) || isSubStructure(A.right,B));
}
public boolean judge(TreeNode A,TreeNode B){
//B为null说明B遍历结束了,B所有的节点都在A里。(当A和B都为null的时候也正好能跳过,也返回true)
if(B == null){
return true;
}
//当A为null时(B不为null),说明B中有的A中没有,A不包含B。或A不为null,但是值不匹配,也不行
if(A == null || A.val != B.val){
return false;
}
//往下都需要满足
return judge(A.left,B.left) && judge(A.right,B.right);
}