这道题思路好想,前序遍历A树的结点,与B树的头节点值进行比较,如果相等,开始判断是否为子树。
难的是,一些边界条件。
我的代码
public boolean isSubStructure(TreeNode A, TreeNode B) {
if(B == null)
return false;
if(A == null)
return false;
return VLR(A, B);
}
public boolean VLR(TreeNode A, TreeNode B) {
boolean result = false;
boolean result_l = false;
boolean result_r = false;
if(A!=null&B!=null) {
if(A.val == B.val) {
result = judgeSub(A,B);
}
if(result == true) {
return true;
}else {
if(A.left!=null) {
result_l = VLR(A.left,B);
}
if(A.right!=null) {
result_r = VLR(A.right,B);
}
result = result_l||result_r;
}
}
return result;
}
public boolean judgeSub(TreeNode A, TreeNode B) {
boolean result = true;
if(B.val == A.val) {
if(A.left!=null&&B.left!=null) {
result = judgeSub(A.left,B.left);
}
//if A has next, B doesn't, result == true,don't need change
if(result == false) {
return result;
}
if(A.right!=null&&B.right!=null) {
result = judgeSub(A.right,B.right);
}
if(result == false) {
return result;
}
if((A.left == null && B.left != null)||(A.right == null && B.right != null)) {
return false;
}
}else {
return false;
}
return result;
}
答案的代码
public boolean isSubStructureAnswer(TreeNode A, TreeNode B) {
boolean result = false;
if(A!=null&&B!=null) {
if(A.val == B.val) {
result = judgeSubAnswer(A,B);
}
if(!result) {
result = isSubStructureAnswer(A.left,B);
}
if(!result) {
result = isSubStructureAnswer(A.right,B);
}
}
return result;
}
public boolean judgeSubAnswer(TreeNode A, TreeNode B) {
if(B == null)
return true;
if(A == null)
return false;
if(A.val != B.val)
return false;
return judgeSubAnswer(A.left,B.left) && judgeSubAnswer(A.right,B.right);
}
对照了一下,在遍历的时候和在判断的时候,我的边界条件判断特别混乱。
在进行遍历的时候,答案的方法也更加高明,只用一个result变量,如果为false,那么再进行接下来的遍历,代码上,比我用或要更直观。
实际上,在进行是否为子树的判断的时候,要判断的就是当前节点是否存在,结点的值是否相等,在当前的递归判断当前对应的结点是否存在,要比在当前递归判断下一个递归的左右结点是否存在,要省事的多,因为这是一个结点与一对节点的边界判断的对比。