「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」
题目介绍
给你一个二叉树的根节点 root , 检查它是否轴对称。
示例1
输入: root = [1,2,2,3,4,4,3]
输出: true
示例2
输入: root = [1,2,2,null,3,null,3]
输出: false
提示:
- 树中节点数目在范围
[1, 1000]内 -100 <= Node.val <= 100进阶: 你可以运用递归和迭代两种方法解决这个问题吗?
解题思路
这道题乍看之下好像挺难解的,但是如果不看根节点的话,左右两棵子树是呈镜像对称的,那么如果把其中一棵子树左右翻转不就和 leetcode-100 相同的树 这道题完全一样了吗?
因此,我们完全可以借鉴这道题的解法来解决今天的这道题,接下来分别利用递归和迭代来解决这道题
思路一:递归
如果抛开根节点不看,我们可以依次比较两棵子树镜像相对的节点,例如左子树的左节点和右子树的右节点进行比较,除非两个节点完全一致,否则就不是对称二叉树
解题步骤
- 比较对称两个位置的节点是否都为空,如果是,返回
true - 比较对称两个位置的节点是不是一空一非空或者两个节点的值不相等,都证明不是对称二叉树,返回
false - 继续比较左子树的左节点和右子树的右节点,左子树的右节点和右子树的左节点
注意
根节点是与自身镜像对称的,所以我们可以从比较两个根节点开始我们的递归过程
解题代码
var isSymmetric = function(root) {
return isSame(root, root)
};
var isSame = function(p, q) {
if (!p && !q) return true
if (p && !q || !p && q || p.val !== q.val) return false
return isSame(p.left, q.right) && isSame(p.right, q.left)
}
思路二:迭代
迭代同样从比较两个根节点开始,每次将对称位置的节点入队,然后从对首出队两个节点进行比较
解题步骤
- 定义一个队列
queue用于存放节点,为了能够正常迭代,将root、root插入到队列queue中 - 如果队列
queue不为空,则出队前两个节点,分别是两棵子树镜像对称位置的节点(两个根节点也可以看成镜像对称) - 如果出队的两个节点都为空节点,则继续出队接下来的两个节点
- 如果出队的两个节点为一空一非空,或者是两个节点的值不相等,直接返回
false,结束遍历 - 将第一个节点的左节点和第二个节点的右节点分别入队
- 将第一个节点的右节点和第二个节点的左节点分别入队
- 重复步骤 2-6,直到队列
queue为空,说明两棵树的所有镜像对称的节点都相同,返回true
解题代码
var isSymmetric = function(root) {
const queue = [root, root]
while (queue.length) {
const node1 = queue.shift()
const node2 = queue.shift()
if (!node1 && !node2) continue
if (!node1 && node2 || node1 && !node2 || node1.val !== node2.val) return false
queue.push(node1.left)
queue.push(node2.right)
queue.push(node1.right)
queue.push(node2.left)
}
return true
};