100. 相同的树
链接:https://leetcode-cn.com/problems/same-tree/
题目描述见链接内容。
解法1:广度优先搜索
占了便宜的是昨天正好做到二叉树遍历的题目,所以今天比较顺利的完成了,一开始想用深度优先搜索完成,但是递归的返回结果总是有点糊涂,但是记住了之前的教训,先把简单的、有思路的、即便是暴力算法的解法做出来,再考虑别的解法
声明了两个临时数组,分别放置p
和q
的后续节点,然后去遍历这两个数组就可以了,需要把两棵树节点存在情况不一致时分类别考虑,思路就清晰了:
var isSameTree = function (p, q) {
const queue1 = [p];
const queue2 = [q];
while (queue1.length || queue2.length) {
const current1 = queue1.shift();
const current2 = queue2.shift();
if (current1 && !current2) {
return false;
}
if (!current1 && current2) {
return false;
}
if (current1 && current2) {
if (current1.val !== current2.val) {
return false;
}
queue1.push(current1.left);
queue2.push(current2.left);
queue1.push(current1.right);
queue2.push(current2.right);
}
}
return true;
};
- 时间复杂度:
${O(min(m, n)}$
,其中m
和n
为两个二叉树节点的个数 - 空间复杂度:
${O(min(m, n)}$
,其中m
和n
为两个二叉树节点的个数 - 执行用时:76ms,在所有JavaScript提交中击败了94%的用户,内存消耗:39MB,在所有JavaScript提交中击败了24%的用户
解法2:广度优先搜索优化
在上面的解法的基础上做了一点无意义的优化,少声明了一个队列数组,使用一个就行了,应该称不上一种算法了,充其量是代码简洁一点
var isSameTree = function (p, q) {
const queue = [p, q];
while (queue.length) {
const current1 = queue.shift();
const current2 = queue.shift();
if (current1 && !current2) {
return false;
}
if (!current1 && current2) {
return false;
}
if (current1 && current2) {
if (current1.val !== current2.val) {
return false;
}
queue.push(current1.left);
queue.push(current2.left);
queue.push(current1.right);
queue.push(current2.right);
}
}
return true;
};
- 时间复杂度:
${O(min(m, n)}$
,其中m
和n
为两个二叉树节点的个数 - 空间复杂度:
${O(min(m, n)}$
,其中m
和n
为两个二叉树节点的个数 - 执行用时:80ms,在所有JavaScript提交中击败了83%的用户,内存消耗:38.9MB,在所有JavaScript提交中击败了71%的用户
解法3:深度优先搜索
广度优先完成后,深度优先的思路也清晰了,和官方题解一样,返回两个数递归调用的逻辑运算结果是可以的,我比较笨,声明了一个外部变量和一个内部函数,通过内部函数的递归调用改变外部变量的值(实际上参考了之前的官方题解)
var isSameTree = function (p, q) {
let isSame = true;
function judge(l, r) {
if ((l && !r) || (!l && r)) {
isSame = false;
} else if (l && r) {
if (l.val !== r.val) {
isSame = false;
} else {
judge(l.left, r.left);
judge(l.right, r.right);
}
}
}
judge(p, q);
return isSame;
};
- 时间复杂度:
${O(min(m, n)}$
,其中m
和n
为两个二叉树节点的个数 - 空间复杂度:
${O(min(m, n)}$
,其中m
和n
为两个二叉树节点的个数 - 执行用时:80ms,在所有JavaScript提交中击败了83%的用户,内存消耗:38.7MB,在所有JavaScript提交中击败了91%的用户