题目链接:另一颗树的子树
解题思路:
1.有两棵树A、B,其根节点分别为root和subRoot。先判断A和B是否相同,如果相同,返回true;否则进入第2步;
2.判断树B是不是A的左子树,如果是,返回true;否则,再判断B是不是A的右子树,如果是,返回true;如果不是,此时B既不是A的左子树又不是A的右子树,则B不是A的子树,返回false。举例图示如下:
代码实现:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
//判断以root为根节点的树和以subRoot为根节点的树是否相同
if(isSameTree(root,subRoot)){
return true;
}
//以subRoot为根的树是以root为根的树的左子树
if(isSubtree(root.left,subRoot)){
return true;
}
以subRoot为根的树是以root为根的树的右子树
if(isSubtree(root.right,subRoot)){
return true;
}
//走到这里时,subRoot树与root树几部相同,也不是其左子树或右子树
return false;
}
//判断以p节点为根节点的树和以q节点为根节点的树是否相同
public boolean isSameTree(TreeNode p, TreeNode q) {
//思路:对p树和q树的根节点
//1、如果一个为空,一个不为空,两棵树不同;
//2、如果两个都为空,返回true;
//3、如果两个都不为空,且值不同,则两棵树不同;
//4、如果两个都不为空,且值相同,则继续判断
//p.left与q.left,p.right与p.right是否相同,如果两者都相同,则两棵树相同,否则不相同
if(p == null && q != null || p != null && q == null){
return false;
}
if(p == null && q == null){
return true;
}
//走到这里时,p、q都不为空
if(p.val != q.val){
return false;
}
//走到这里,p、q都不为空且值相同
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
}
说明:public boolean isSameTree(TreeNode p, TreeNode q)方法是手动写的一个方法,用于判断以p为根节点的树和以q为根节点的树是否相同(内容上的相同)。
程序运行结果如下:
分析:出现空指针异常。原因是没有对参数root是否为null做出判断。如果root == null而subRoot != null,则会在第2个if语句条件判断部分发生空指针异常。
debug:由于当 root == null 且subRoot == null的情况,已经在第一个if语句中进行执行判断了,我们只需补充root == null且subRoot != null的情况。即在第一个if语句之后补充如下语句即可:
if(root == null && subRoot != null){
return false;
}
最终代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if(isSameTree(root,subRoot)){
return true;
}
if(root == null && subRoot != null){
return false;
}
if(isSubtree(root.left,subRoot)){
return true;
}
if(isSubtree(root.right,subRoot)){
return true;
}
return false;
}
//判断以p节点为根节点的树和以q节点为根节点的树是否相同
public boolean isSameTree(TreeNode p, TreeNode q) {
//思路:对p树和q树的根节点
//1、如果一个为空,一个不为空,两棵树不同;
//2、如果两个都为空,返回true;
//3、如果两个都不为空,且值不同,则两棵树不同;
//4、如果两个都不为空,且值相同,则继续判断
//p.left与q.left,p.right与p.right是否相同,如果两者都相同,则两棵树相同,否则不相同
if(p == null && q != null || p != null && q == null){
return false;
}
if(p == null && q == null){
return true;
}
//走到这里时,p、q都不为空
if(p.val != q.val){
return false;
}
//走到这里,p、q都不为空且值相同
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
}