[路飞] 40——leetcode - 662. 二叉树最大宽度

218 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

662. 二叉树最大宽度

题目分析

给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree) 结构相同,但一些节点为空。

每一层的宽度被定义为两个端点(该层最左和最右的非空节点,两端点间的null节点也计入长度)之间的长度。

思路讲解

  • 给整个树做一个编号,从左到右,从上到下开始
  • root 的编号为1,那么root的左孩子编号就为2, 右孩子就为3
  • root.left 的index = root的index*2
  • root.right 的index = root的index*2 + 1
  • 然后我们定义一个变量max 来记录宽度的最大值,每层的序号相减完毕和max进行比较取最大值
  • 宽度width就是 Rindex - Lindex + 1

宽度优先搜索顺序遍历每个节点的过程中,我们记录节点的 position 信息,对于每⼀个深度,第⼀个遇到的节点是最左边的节点,最后⼀个到达的节点是最右边的节点。

示例

输入: 

      1
     / \
    3   2 
   /        
  5      

输出: 2
解释: 最大值出现在树的第 2 层,宽度为 2 (3,2)。

输入: 

          1
         / \
        3   2
       /     \  
      5       9 
     /         \
    6           7
输出: 8
解释: 最大值出现在树的第 4 层,宽度为 8 (6,null,null,null,null,null,null,7)。

代码

/*
 * @lc app=leetcode.cn id=662 lang=javascript
 *
 * [662] 二叉树最大宽度
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
   * 给整个树做一个编号,从左到右,从上到下开始
   * root 的编号为1,那么root的左孩子编号就为2, 右孩子就为3
   * root.left 的index = root的index*2
   * root.right 的index = root的index*2 + 1
   * 然后我们定义一个变量max 来记录宽度的最大值,每层的序号相减完毕和max进行比较取最大值
   * 宽度width就是 Rindex - Lindex + 1
 * @return {number}
 */
var widthOfBinaryTree = function(root) {
  if (!root) return 0
  // 定义一个二维数组存储当前层的序号和节点
  // 1n 数太大了,需要用大数来表示
  let max = 1n, que = [[0n, root]];
  while (que.length) {
    let width = que[que.length - 1][0] - que[0][0] + 1n
    if (width > max) max = width
    let temp = []
    for (const [i, q] of que) {
      q.left && temp.push([ i * 2n, q.left])
      q.right && temp.push([ i * 2n + 1n, q.right])
    }
    que = temp
  }
  return Number(max)
};
// @lc code=end