[路飞]_二叉树最大宽度

258 阅读2分钟

662. 二叉树最大宽度

题目

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

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

示例1

输入: 

           1
         /   \
        3     2
       / \     \  
      5   3     9 

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

序言

略微扫了一眼题目,看到获取树最大宽度;熟啊,这不是二叉树层序遍历的变种吗;DFS搞定;题都不看了,马上整了一段代码上去;运行~凉凉~~

尴尬

细读题目要求,两端点间的null节点也计入长度;我想说打扰了。

题解

两端点间的null节点也计入长度;也就是是说,要解决最大宽地问题,要得到当前节点在满二叉树的位置;

比如:下面二叉树

           1
         /   \
        3     2
       / \     \  
      5   3     9 

3在第2层第1位;2在第2层第2位;
5在第2层第1位,9在第3层第4位

二叉树最大宽度9和5所在的位置之差;4-1+1 = 4;

但是有个问题,找到层数,如何确定当前节点在所在层数的位置也是个问题啊;

又卡壳了;

在思考,我知道层序遍历,那我就按照层序遍历时候节点所在的位置记录不就好了;

怎么理解上面这句话;

           1
         /   \
        3     2
       / \     \  
      5   3     9 

还是这个节点;我把这个节点改成一维数组可以得到[1,3,2,5,3,null,9]对不对; 是不是也可以变成二维数组

// 二维数组
var array = [
  ...[1],
  ...[2, 3],
  ...[5, 3, null, 9],
]
// 一维数组
var array = [1,3,2,5,3,null,9]

9在一维数组下标是6,5在一维数组下标是3;得到6-3+1 = 4;

好了,现在问题转换为找节点下标;得到下标之差最大值即可

处理一下边界

如果层数较多,下标可能超出js的数字表示范围;所以这里使用BigInt这个语法,防止数据超出

代码

var widthOfBinaryTree = function (root) {
  let result = 0n
  let map = new Map()
  dfs(root, 1, 1n, [])
  return result
  function dfs(node, level, index) {
   
    if (node === null) return
    if (!map.get(level)) {
      map.set(level, index)
    }
    const val = index - (map.get(level) || 0n) + 1n
    if (val > result) result = val
    dfs(node.left, level + 1, index * 2n)
    dfs(node.right, level + 1, index * 2n + 1n)
  }
}