[路飞]对称二叉树

167 阅读2分钟

记录 1 道算法题

对称二叉树

leetcode-cn.com/problems/sy…


一棵树中间轴对称,在广度遍历的时候,需要注意推入数组的时候要区分左右节点。

            a
         b     c
           d     e

这种情况下,第三层推入数组时是 [d,e]。这样看着是对称的,但其实是不对称的,所以要推入 undefined 进行占位,但是不用把一层占满,只需要如果左右节点其中一个有值的话,另一个是空的时候就填入 undefined 就可以了。

例如 [undefined, d, undefined, e],这样就可以判断出不对称。

  1. 广度优先

一开始打算正常从左到右的顺序存,然后判断头和尾是否相等,往中间收缩,但是这样就要遍历两遍,一边判断,一遍收集下一层的节点。

所以优化的方法是改变存入数组时的顺序。

    function isSymmetric(root) {
        const stack = [root.left, root.right]

        while (stack.length) {
          // 改变后前两个节点是应该对称的节点
          const n1 = stack.shift()
          const n2 = stack.shift()
          // 判断是否匹配
          // 如果都是叶子节点就跳过
          if (!n1 && !n2) continue
          if (!n1 || !n2) return false
          if (n1.val !== n2.val) return false

          // 最左边和最右边一起推入
          //  a  b  c  d,假如这一层是这样
          //  ad, bc 的推入
          stack.push(n1.left, n2.right)
          stack.push(n1.right, n2.left)
        }

        return true
      }
  1. 深度优先

就是递归解决了,需要传入两个参数,分别是对称轴左边的节点和对称轴右边的节点。

当左边往左走的时候,右边往右走。当左边往右走的时候,左边往左走。

            a             a
         b      c     c       b

这种情况,当我们处在 a 节点的视角的时候, 左边的 a 往左走,与他对称的右边的 a 是要往右走。

    function isSymmetric(root, root2 = root) {
        // 都是空节点时不用判断
        if (!root && !root2) return true
        // 如果上面没进去,说明至少有一个不是空节点,
        // 如果这里进去了说明至少有一个是空节点,就不匹配。
        if (!root || !root2) return false
        // 比较值
        if (root.val !== root2.val) return false
        // 反着走
        return (
          isSymmetric(root.left, root2.right) &&
          isSymmetric(root.right, root2.left)
        )
    }