题目
给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(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)
}
}