大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。
题目
101. 对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
进阶:
你可以运用递归和迭代两种方法解决这个问题吗?
递归解法
思路
- 判断当前根节点是否存在,存在的话判断左节点和右节点的值是否相等;
- 判断左节点和右节点是否相等之前,先做一个边界值的限制。如果左子节点和右子节点都不存在,说明它们是相等的,如果它们只有一个存在,说明是不相等的;
- 边界判断完之后,判断一下当前两个值是否相等,如果相等了,递归的判断当前左节点的左子节点和右节点的右子节点是否相等,左节点的右子节点和右节点的左子节点是否相等即可;
- 因为是镜像的,我们每轮只需要判断我们要比较的两个节点是否镜像全等即可。
实现
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
return !root || compareNode(root.left, root.right);
};
function compareNode(node1, node2) {
if (!node1 && !node2) return true;
if (!node1 || !node2) return false;
return node1.val === node2.val && compareNode(node1.left, node2.right) && compareNode(node1.right, node2.left)
}
迭代解法
思路
- 除了第一轮,后面每轮的节点数都是双数的,我们只需要维持好他们彼此的关系即可;
- 判断的时候需要先判断节点是否为空节点,如果只有一个节点是空节点说明不匹配;
- 如果两个节点都是空节点的跳过,不进行任何操作;
- 如果两个节点都不是空节点,那么要比较他们的值,而且还有比较第一个节点的左节点和第二个节点的右节点,第一个节点的右节点和第二个节点的左节点的值,我们依次把他们放进下一轮的数组中即可;
- 每一轮一号节点的子节点用
unshift插入数组的最前面,二号节点的子节点用push插入数组的最后面,然后我们取值的时候也是从两边各自取一个,不过需要注意一点,插入的顺序得是1号的右 => 对应2号的左,1号的左对应2号的右,意思就是1号先插入右2号就得先插入左。
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {boolean}
*/
var isSymmetric = function(root) {
if (!root) return true;
let arr = [ root.left, root.right ];
while (arr.length) {
let nextArr = [];
const mid = arr.length / 2;
for (let i = 0; i < mid; i++) {
let first = arr[i], last = arr[arr.length - 1 - i];
// 有一个空节点,排除
if (!!first !== !!last) return false;
// 两个都是空结点,抬走下一位
if (!first) continue;
// 如果值不相等就不用比了
if (first.val !== last.val) {
return false;
} else {
// 前面的放前面,后面的放后面, 形成镜像
nextArr.unshift(first.right);
nextArr.unshift(first.left);
nextArr.push(last.left);
nextArr.push(last.right);
}
}
arr = nextArr;
}
return true;
};
看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。