/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
//写递归算法只用考虑到怎么分,只用考虑最表面的一块,剩下的如何递归的只用设计好递归出口即可
public boolean isSameTree(TreeNode p, TreeNode q) {
//递归出口
if(p == null && q != null) return false;
if(p != null && q == null) return false;
if(p == null && q == null) return true;
if(p.val != q.val) return false;//p、q都不为空的情况
//递归
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
代码优化:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
//写递归算法只用考虑到怎么分,只用考虑最表面的一块,剩下的如何递归的只用设计好递归出口即可
public boolean isSameTree(TreeNode p, TreeNode q) {
/*if(p == null && q != null) return false;
if(p != null && q == null) return false;
if(p == null && q == null) return true;*/
//递归出口
//上面注释这一块可以用下面这一行解决
if(p == null || q == null) return p == q;
if(p.val != q.val) return false;
//递归
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}
解法二(非递归):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
/*
* 先写算法思路,再写代码
* 用两个队列来存放两棵二叉树的结点,非空结点才放入队列中
* 类似于层次遍历,两个队列从队首弹出一个结点时,比较两个弹出的结点的左右子结点的内容,
* 然后再将两个结点的左右非空子结点分别放入两个队列中
*/
Queue<TreeNode> P = new LinkedList<TreeNode>();
Queue<TreeNode> Q = new LinkedList<TreeNode>();
if(p == null || q == null) return p == q;
if(p.val != q.val) return false;
//根结点要是非空的
P.add(p);
Q.add(q);
while(!P.isEmpty() &&!Q.isEmpty()){
p = P.poll();
q = Q.poll();
if(p.left == null && q.left != null) return false;
if(p.left != null && q.left == null) return false;
//两个弹出结点的左子结点都为空时不管
if(p.left != null && q.left != null){
if(p.left.val == q.left.val){
P.add(p.left);
Q.add(q.left);
}
else{
return false;
}
}
if(p.right == null && q.right != null) return false;
if(p.right != null && q.right == null) return false;
//两个弹出结点的右子结点都为空时不管
if(p.right != null && q.right != null){
if(p.right.val == q.right.val){
P.add(p.right);
Q.add(q.right);
}
else{
return false;
}
}
}
return P.size() == Q.size();
}
}
解法二(非递归)代码优化:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
/*
* 先写算法思路,再写代码
* 用两个队列来存放两棵二叉树的结点,非空结点才放入队列中
* 类似于层次遍历,两个队列从队首弹出一个结点时,比较两个弹出的结点的左右子结点的内容,
* 然后再将两个结点的左右非空子结点分别放入两个队列中
*/
Queue<TreeNode> P = new LinkedList<TreeNode>();
Queue<TreeNode> Q = new LinkedList<TreeNode>();
if(p == null || q == null) return p == q;
if(p.val != q.val) return false;
P.add(p);
Q.add(q);
while(!P.isEmpty() &&!Q.isEmpty()){
p = P.poll();
q = Q.poll();
if(p.val != q.val) return false;
if(p.left != null) P.add(p.left);
if(q.left != null) Q.add(q.left);
//比上面的解法二巧妙的方法,不用判断p、q的子结点是否为空,是否忽略,
//放入队列后通过队列P和Q的长度是否相等来判断两棵树的这一部分结构是否相同,因为都只判断了左子结点,队列长度要么加0要么加1
if(P.size() != Q.size()) return false;//return P.size() == Q.size()这种写法不对,直接返回了下面的代码永远不会执行
if(p.right != null) P.add(p.right);
if(q.right != null) Q.add(q.right);
//比上面的解法二巧妙的方法,不用判断p、q的左子结点是否为空,是否忽略,
//放入队列后通过队列P和Q的长度是否相等来判断两棵树的这一部分结构是否相同,因为都只判断了右子结点,队列长度要么加0要么加1
if(P.size() != Q.size()) return false;
}
return P.size() == Q.size();
}
}