[路飞]_对称二叉树

146 阅读3分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战

leetcode-101 对称二叉树

题目介绍

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例1

image.png

输入: root = [1,2,2,3,4,4,3]
输出: true

示例2

image.png

输入: root = [1,2,2,null,3,null,3]
输出: false

提示:

  • 树中节点数目在范围 [1, 1000] 内
  • -100 <= Node.val <= 100 进阶: 你可以运用递归和迭代两种方法解决这个问题吗?

解题思路

这道题乍看之下好像挺难解的,但是如果不看根节点的话,左右两棵子树是呈镜像对称的,那么如果把其中一棵子树左右翻转不就和 leetcode-100 相同的树 这道题完全一样了吗?

因此,我们完全可以借鉴这道题的解法来解决今天的这道题,接下来分别利用递归和迭代来解决这道题

思路一:递归

如果抛开根节点不看,我们可以依次比较两棵子树镜像相对的节点,例如左子树的左节点和右子树的右节点进行比较,除非两个节点完全一致,否则就不是对称二叉树

解题步骤

  1. 比较对称两个位置的节点是否都为空,如果是,返回 true
  2. 比较对称两个位置的节点是不是一空一非空或者两个节点的值不相等,都证明不是对称二叉树,返回 false
  3. 继续比较左子树的左节点和右子树的右节点,左子树的右节点和右子树的左节点 注意
    根节点是与自身镜像对称的,所以我们可以从比较两个根节点开始我们的递归过程

对称二叉树.gif

解题代码

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)
}

思路二:迭代

迭代同样从比较两个根节点开始,每次将对称位置的节点入队,然后从对首出队两个节点进行比较

解题步骤

  1. 定义一个队列 queue 用于存放节点,为了能够正常迭代,将 rootroot 插入到队列 queue
  2. 如果队列 queue 不为空,则出队前两个节点,分别是两棵子树镜像对称位置的节点(两个根节点也可以看成镜像对称)
  3. 如果出队的两个节点都为空节点,则继续出队接下来的两个节点
  4. 如果出队的两个节点为一空一非空,或者是两个节点的值不相等,直接返回 false,结束遍历
  5. 将第一个节点的左节点和第二个节点的右节点分别入队
  6. 将第一个节点的右节点和第二个节点的左节点分别入队
  7. 重复步骤 2-6,直到队列 queue 为空,说明两棵树的所有镜像对称的节点都相同,返回 true

对称二叉树(1).gif

解题代码

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
};