输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
这个题首先就是判断树A和树B是否为空了。
接下来就是在A里面找跟B的根节点相等的点!
找到了以后,因为是判断B是否是A的子序列,所以B是那个小的集合,所以就深度遍历B,然后A也跟B一样的方式遍历!B找左子树,A也找左子树,B找右子树,A也找右子树!
每个节点就判断它自己是否和规范以及,它的孩子是否符合规范。
如果B一个节点的某个孩子为空,那就证明这个点就是叶子节点了,A对应的点只要相等就行了,没必要A的对应孩子也是空,毕竟B是人家A的一部分。
我写的垃圾代码如下:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean is_equal(TreeNode root2,TreeNode root1) {
if(root2==null)
return true;
if(root1==null)
return false;
if (root2.val==root1.val)
return is_equal(root2.left, root1.left) && is_equal(root2.right, root1.right) ;
else
return false;
}
public boolean find_root(TreeNode root1,TreeNode root2) {
if (root1.val!=root2.val)
{
if(root1.left!=null)
return find_root(root1.left, root2);
if(root1.right!=null)
return find_root(root1.right, root2);
}
else {
if(is_equal(root2, root1)==true)
return true;
else {
if(root1.left!=null)
return find_root(root1.left, root2);
if(root1.right!=null)
return find_root(root1.right, root2);
}
}
return false;
}
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root2 ==null || root1==null)
return false;
else
return find_root(root1,root2);
}
}
这个代码好在哪里呢?好在分的比较开,每个函数实现的功能比较单一,看了好理解点!(菜鸡如此安慰自己)
差在哪里呢?没优化!对就是没优化!
上个大神的代码:
class Solution {
bool isSubtree(TreeNode* pRootA, TreeNode* pRootB) {
if (pRootB == NULL) return true;
if (pRootA == NULL) return false;
if (pRootB->val == pRootA->val) {
return isSubtree(pRootA->left, pRootB->left)
&& isSubtree(pRootA->right, pRootB->right);
} else return false;
}
public:
bool HasSubtree(TreeNode* pRootA, TreeNode* pRootB)
{
if (pRootA == NULL || pRootB == NULL) return false;
return isSubtree(pRootA, pRootB) ||
HasSubtree(pRootA->left, pRootB) ||
HasSubtree(pRootA->right, pRootB);
}
};
这个办法用到了判断的短路特性!
也就是if(a||b||c||d) 只要其中一个满足了是true,后面的就不用执行了!像不像if判断句?
或者是if(a&&b&&c&&d),只要一个满足为false,后面的也不执行!是不是也是if判断句的优化!
两个代码的差距就是大神和菜鸡的差距!
菜鸡需要继续写代码!