Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目分析
给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(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