二叉树的最大宽度

97 阅读2分钟

二叉树的最大宽度

  1. 解题思路

    • 可以借助完全二叉树的性质
      • 完全二叉树可以通过一个数组来进行存储,可以省略leftright指针,可以用下标表示节点之间的关系
      • 左节点可以用2 * index, 右节点可以用2 * index + 1 表示
    • 可以利用队列相关知识达到每层节点的遍历
  2. 上代码

    var widthOfBinaryTree = function(root) {
        const queue = [] // 用来存储每层节点
        const map = new Map() // 用来记录每次节点对应的编号
        let res = 0 // 用来记录最大值
        if(!root) return 0
        queue.push(root)
        // 初始化根节点的编号
        map.set(root, 0)
        while(queue.length) {
            // r 和 l 用来记录每层的最大值和最小值
            // 初始化 r 和 l
            let r = l = map.get(queue[0])
            const count = queue.length // 用来记录每层的数量,那么我们就知道这一层需要遍历多少次
            for(let i = 0; i < count; i ++) {
                const item = queue[0]
                let index = map.get(item)
                r = index // 需要每次都要更新一下最大值
                if (item.left){
                    queue.push(item.left)
                    map.set(item.left, 2 * index)
                }
                if (item.right){
                    queue.push(item.right)
                    map.set(item.right, 2 * index + 1) 
                }
                queue.shift()
            }
            res = Math.max(res, r - l + 1)
        }
        return res
    }
    
  3. 当我们将上述代码进行提交的时候,会发现有测试用例不通过,返回的是NaN.原因是我们的编号超出了数字的表示。我们可以在计算编号的时候可以用父节点的编号减去父节点那一层的最小标号所以

  var widthOfBinaryTree = function(root) {
      const queue = [] // 用来存储每层节点
      const map = new Map() // 用来记录每次节点对应的编号
      let res = 0 // 用来记录最大值
      if(!root) return 0
      queue.push(root)
      // 初始化根节点的编号
      map.set(root, 0)
      while(queue.length) {
          // r 和 l 用来记录每层的最大值和最小值
          // 初始化 r 和 l
          let r = l = map.get(queue[0])
          const count = queue.length // 用来记录每层的数量,那么我们就知道这一层需要遍历多少次
          for(let i = 0; i < count; i ++) {
              const item = queue[0]
              let index = map.get(item)
              r = index // 需要每次都要更新一下最大值
              if (item.left){
                  queue.push(item.left)
                  map.set(item.left, 2 * (index - l))
              }
              if (item.right){
                  queue.push(item.right)
                  map.set(item.right, 2 * (index - l) + 1) 
              }
              queue.shift()
          }
          res = Math.max(res, r - l + 1)
      }
      return res
  }