【路飞】平衡二叉树

100 阅读2分钟

记录 1 道算法题

平衡二叉树

leetcode-cn.com/problems/ba…


如果左子树的高度和右子树的高度相差超过 1,就返回 false。

空树 返回 true。

高度是什么呢,就是左节点一直到他的最深的left节点的层数差。

             a
          b
      c      d
        f
          e
          
     a 的高度 就是 a 到 最底层 e 的层数 5
     b 的高度 就是 b 到 最底层 e 的层数 4
     d 的高度 则是 0, 因为 d 就是叶子节点了。
     c 的高度 是 3
     以此类推
     
     f 的没有左节点,所以他的左节点高度是 0 , 右节点高度是 1, 他们相差1 所以合理。
     c 的左节点没有,所以是 0 但是右节点 f 的高度是 2,所以 不合理。

解题前先介绍一下计算树的高度的做法,计算树的高度用到了累加的办法。

    function count(root) {
        // 叶子节点的虚空子节点
        if (!root) return 0
        // 递归会获得从底层一直累加上来的高度
        const left = root(root.left)
        const right = root(root.right)
        // 高度采用 左节点和右节点之间最高的那个,即最深的。
        // 然后加1,是加上自己,实现累加。
        return Math.max(left, right) + 1
    }

有时候递归容易想复杂,其实可以抛开很多东西,就光看,我们知道了某个父节点的左节点的高度和右节点的高度,那么我们就可以知道他们的高度差,所以是Math.abs(left - right) 有没有超过 1。

再做一个优化就是我们可以让他提早返回,因为一旦有一个地方高度差不合格,那整棵树就不是平衡二叉树了。所以我们用一个小于0或者其他非 0-n数字的东西做额外标记,如果哪一层不合理就之间抛出来,外层的递归就会拿得到,如果里面抛了,外层之间抛。这样可以提早返回。

    function isBalanced(root) {
        // 处理空树
        if (!root) return true

        function f(node) {
            // 和上面计算高度一样
          if (!node) return 0
          const left = f(node.left)
          // -1 作为标记
          if (left < 0) return -1
          const right = f(node.right)
          if (right < 0) return -1
            
           // 在返回树的高度之前拦截判断一下,如果高度差不合格就之间返回了。
           // 源头的不合理判断抛出
          if (Math.abs(left - right) > 1) {
            return -1
          }
            // 正常则继续累加高度
          return Math.max(left, right) + 1
        }
        
        return f(root) >= 0
    }

结束