题目描述
给定两个二叉树,编写一个函数来检验它们是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入: 1 1
/ \ / \
2 3 2 3
[1,2,3], [1,2,3]
输出: true
示例 2:
输入: 1 1
/ \
2 2
[1,2], [1,null,2]
输出: false
示例 3:
输入: 1 1
/ \ / \
2 1 1 2
[1,2,1], [1,1,2]
输出: false
解题
方法一:递归
从根结点出发,向左右子树分别递归,也可以称为树的深度优先遍历,按照先序遍历顺序。
递归结束条件:
两个树(子树)根结点都为null,返回true,
一个为null,一个不为null,返回false,
都不为null,但值不同,返回false,
值相同,递归左子树与右子树,两个递归调用都为true时结果为true,
&&为短路运算,左边为false右边就不会执行。
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p == null && q == null) return true;
if(p == null || q == null) return false;
if(p.val!=q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
方法二:层次优先遍历
按层遍历,使用队列存储已访问的结点,每次从队头取结点,比较取出结点的子结点,子结点值相同时加入队尾,直到队列为空则树相同。
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null && q==null) return true;
if(!check(p, q)) return false;
ArrayDeque<TreeNode> queP = new ArrayDeque<>();
ArrayDeque<TreeNode> queQ = new ArrayDeque<>();
queP.addLast(p); queQ.addLast(q);
while(!queP.isEmpty()){
p=queP.removeFirst();
q=queQ.removeFirst();
if(!check(p, q)) return false;
if(p!=null){
if(!check(p.left, q.left)) return false;
if(p.left!=null){
queP.addLast(p.left);
queQ.addLast(q.left);
}
if(!check(p.right, q.right)) return false;
if(p.right!=null){
queP.addLast(p.right);
queQ.addLast(q.right);
}
}
}
return true;
}
public boolean check(TreeNode p, TreeNode q){
if(p == null && q == null) return true;
if(p == null || q == null) return false;
if(p.val != q.val) return false;
return true;
}