相同的树
给你两棵二叉树的根节点
p
和q
,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入:p = [1,2,3], q = [1,2,3] 输出:true示例 2:
输入:p = [1,2], q = [1,null,2] 输出:false示例 3:
输入:p = [1,2,1], q = [1,1,2] 输出:false
方法一: 广度优先搜索 (第一种是我写的,第二种是官方题解)
import java.util.Deque;
import java.util.LinkedList;
/**
* 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 isSameTree(TreeNode p, TreeNode q) {
Deque<TreeNode> queue1 = new LinkedList<>();
Deque<TreeNode> queue2 = new LinkedList<>();
if (p == q) {
return true;
}
queue1.offer(p);
queue2.offer(q);
TreeNode temp1, temp2;
temp1 = temp2 = null;
while (!(queue1.isEmpty() && queue2.isEmpty())) {
temp1 = queue1.poll();
temp2 = queue2.poll();
if (temp1 == null ^ temp2 == null) {
return false;
}
if (temp1.val != temp2.val) {
return false;
}
if (temp1.left != null && temp2.left != null) {
queue1.offer(temp1.left);
queue2.offer(temp2.left);
} else if (temp1.left != temp2.left) {
return false;
}
if (temp1.right != null && temp2.right != null) {
queue1.offer(temp1.right);
queue2.offer(temp2.right);
} else if (temp1.right != temp2.right) {
return false;
}
}
return (queue1.isEmpty() && queue2.isEmpty());
}
}
import java.util.Deque;
import java.util.LinkedList;
public boolean isSameTree(TreeNode p, TreeNode q) {
Deque<TreeNode> queue1 = new LinkedList<>();
Deque<TreeNode> queue2 = new LinkedList<>();
if (p == q) {
return true;
} else if (p == null || q == null) {
return false;
}
queue1.offer(p);
queue2.offer(q);
TreeNode temp1, temp2;
temp1 = temp2 = null;
while (!(queue1.isEmpty() && queue2.isEmpty())) {
temp1 = queue1.poll();
temp2 = queue2.poll();
if (temp1.val != temp2.val) {
return false;
}
if (temp1.left == null ^ temp2.left == null) {
return false;
}
if (temp1.right == null ^ temp2.right == null) {
return false;
}
if (temp1.left != null) {
queue1.offer(temp1.left);
}
if (temp2.left != null) {
queue2.offer(temp2.left);
}
if (temp1.right != null) {
queue1.offer(temp1.right);
}
if (temp2.right != null) {
queue2.offer(temp2.right);
}
}
return queue1.isEmpty() && queue2.isEmpty();
}
方法二: 深度优先搜索
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
} else if (p == null || q == null) {
return false;
} else if (p.val != q.val) {
return false;
}
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
时间复杂度T(n)= O(min(m,n)),m 、n为二叉树的节点数。
空间复杂度S(n)=O(min(m,n)),对于深度优先搜索,空间复杂度取决于递归调用的层数,递归调用的层数不会超过较小的二叉树的大高度。对于广度优先搜索,空间复杂度取决于队列中的节点数,队列中的元素数量最多不超过二叉树的节点数。
这道题真的很好,归根结底,实际上就是二叉树的遍历方式,对于广度优先搜索,使用了队列这种数据结构,遍历方式是层序遍历;深度优先搜索则是使用递归的思想,遍历方式是先序遍历,广度优先搜索的方式,第一种是我自己写的,逻辑很乱, 对比官方给出的题解,过程大致一样,但又有一点区别,我也很晕看不出来哪个更好。上述内容如果有错误的地方,希望大佬们可以指正。我一直在学习的路上,您的帮助使我收获更大!觉得对您有帮助的话,还请点赞支持!我也会不断更新文章!