剑指 Offer 26. 树的子结构

115 阅读1分钟
class Solution {
    public boolean isSubStructure(TreeNode A, TreeNode B) {
        return (A != null && B != null) && (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B));
        //更宏观的用递归去conver树结构的可能性空间,三种可能性空间,根,左树,右树
    }
    boolean recur(TreeNode A, TreeNode B) {
        if(B == null) return true;
        if(A == null || A.val != B.val) return false; // 两个条件 a比b树短或,a.val != b.val
        return recur(A.left, B.left) && recur(A.right, B.right); //继续递归左子树,右子树
    }
}

注释:题目的要求是B树是A树的子树,所以针对recur函数递归结束条件有两种,一种是A树比B树大,所以b== null;return ture,所有相等将继续比较,直到b==null,代表b树完成 一种是比较过程中a树节点不等于b树节点,返回false,有两种可能a == null比b短,a.val != b.val

如果这两者都不满足,继续递归两棵树比较。这是递归子树的比较条件。

关于递归子树的条件,可能是从根开始,又或者是从a.left左子树开始,又或从a.right右子树开始。

 public boolean isSubStructure(TreeNode A, TreeNode B) {
        return (A != null && B != null) && (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B));
    }

这个条件在我看来写得非常精妙,递归比较的前提是a 和 b树不为空,开始递归又有三种可能 从根递归比较 || 从左子树递归比较 || 从右子树递归比较

return (A != null && B != null) && (recur(A, B) || isSubStructure(A.left, B) || isSubStructure(A.right, B));

从题主的解题思路来反思自已的思考,很容易陷入细节,题主的思考精练简洁,又不失严谨。