题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
题解参考:https://blog.nowcoder.net/n/0a7ab5e0ea0749279462d9e413232a94?f=comment
首先分清子树和子结构
子树
一棵大树A,一棵小树B,若B是A的子树,则:
- B和A的结点值完全相同,它们俩的左子树,右子树的值也完全相同
- 或者B的左孩子和A的结点值完全相同,它们俩的左子树,右子树所有结点值也完全相同
- 或者B的右孩子和A的结点值完全相同,它们俩的左子树,右子树所有结点的值也完全相同
举个例子:
这棵大树的子树有:
- 4 和 5 对应的两棵子树
- 3 本身自己完整的一棵树
- 而图上用小框圈出来来的不是 3 这棵大树的子树
所以在结点值相同的情况下,如果子树先达到null,那么一定是其子树
public class IsSubTree {
public boolean HasSubtree(TreeNode root1, TreeNode root2) {
if (root1 == null || root2 == null) {
return false;
}
return judgeSubTree(root1, root2) ||
judgeSubTree(root1.left, root2) ||
judgeSubTree(root1.right, root2);
}
private boolean judgeSubTree(TreeNode root1, TreeNode root2) {
if (root2 == null) {
return true;
}
if (root1 == null) {
return false;
}
if (root1.val != root2.val) {
return false;
}
return judgeSubTree(root1.left, root2.left) &&
judgeSubTree(root1.right, root2.right);
}
}
子结构
图中的黄色框和小框都是整棵树的子结构,所以只要找到符合树的一部分树节点就即可
/**
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 root1,TreeNode root2) {
if(root1 == null || root2 == null) return false;
return (subtree(root1, root2) || subtree(root1.right, root2) || subtree(root1.left, root2));
}
public boolean subtree(TreeNode roota,TreeNode rootb){
if(rootb == null) return true;
if(roota == null) return false;
if(roota.val != rootb.val){
return subtree(roota.left,rootb) || subtree(roota.right,rootb);
}
return subtree(roota.left,rootb.left) && subtree(roota.right,rootb.right);
}
}
因为子结构不等于子树,只需要一部分相等就可以
所以在当前子树A和B不相等时,不用返回false,而是继续往下遍历