Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述
给定一个二叉树,编写一个函数来获取这个树的最大宽度。树的宽度是所有层中的最大宽度。这个二叉树与满二叉树(full binary tree)结构相同,但一些节点为空。
每一层的宽度被定义为两个端点(该层最左和最右的非空节点,两端点间的null节点也计入长度)之间的长度。
示例 1:
输入:
1
/ \
3 2
/ \ \
5 3 9
输出: 4
解释: 最大值出现在树的第 3 层,宽度为 4 (5,3,null,9)。
示例 2:
输入:
1
/
3
/ \
5 3
输出: 2
解释: 最大值出现在树的第 3 层,宽度为 2 (5,3)。
示例 3:
输入:
1
/ \
3 2
/
5
输出: 2
解释: 最大值出现在树的第 2 层,宽度为 2 (3,2)。
示例 4:
输入:
1
/ \
3 2
/ \
5 9
/ \
6 7
输出: 8
解释: 最大值出现在树的第 4 层,宽度为 8 (6,null,null,null,null,null,null,7)。
注意: 答案在32位有符号整数的表示范围内。
二、思路分析
借助队列结构, 把树的每行(每层)都加到队列中去;
每次处理一行,给每个节点编号,记录一行中最小编号和最大编号
每次处理:上一行出队列,下一行(上一行的子节点)入队列
三、JavaScript代码
/**
* 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
* @return {number}
*/
var widthOfBinaryTree = function(root) {
let ans = 0; // 最终返回结果,记录宽度
let queue = []; //操作队列
queue.push([root,0]); // 初始先把根节点添到队列中,数据结构【当前节点,节点编号】
while(queue.length) {
// 处理每行节点
let countRow = queue.length; // 记录一行节点数量
let l = queue[0][1], r = queue[0][1]; // 记录最小和最大编号
for(let i = 0; i < countRow; i++) {
// 更新行:前节点的子节点加入队列后,把当前节点出队
let queueData = queue.shift()
let node = queueData[0]; // 节点
let ind = queueData[1]; // 节点编号
r = ind;
// 判断当前节点是否有左/有子节点,有就加入队列中
// 减去l的目的:保证每个设置的节点编号从上层节点的最小编号开始(防止超出整数范围,例如只有右子树的,编号会越来越大)
if(node.left) queue.push([node.left, 2* (ind - l)]);
if(node.right) queue.push([node.right, 2* (ind - l)+1])
}
ans = Math.max(ans, r - l + 1)
}
return ans
};