携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
题目描述
给你一棵二叉树的根节点 root ,返回树的 最大宽度 。
树的 最大宽度 是所有层中最大的 宽度 。
每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点,这些 null 节点也计入长度。
题目数据保证答案将会在 32 位 带符号整数范围内。
示例 1:
输入: root = [1,3,2,5,3,null,9]
输出: 4
解释: 最大宽度出现在树的第 3 层,宽度为 4 (5,3,null,9) 。
示例 2:
输入:root = [1,3,2,5,null,null,9,6,null,7]
输出:7
解释:最大宽度出现在树的第 4 层,宽度为 7 (6,null,null,null,null,null,7) 。
示例 3:
输入: root = [1,3,2,5]
输出: 2
解释: 最大宽度出现在树的第 2 层,宽度为 2 (3,2) 。
解题思路
通过题目我们可以知道:每一层的 宽度 被定义为该层最左和最右的非空节点(即,两个端点)之间的长度。将这个二叉树视作与满二叉树结构相同,两端点间会出现一些延伸到这一层的 null 节点,这些 null 节点也计入长度。
既然要求的是宽度,而且是最大宽度,那么第一反应就是 层序遍历,通过层序遍历我们可以获得每层 非null节点 的宽度。
那么这道题需要将 null 节点也包含在内,这可就麻烦了啊。
我们看看这些示例:[1,3,2,5,null,null,9,6,null,7]
哎,这不就是以数组的形式存储二叉树吗,通过下标就能知道每层第一个节点和最后一个节点的宽度,而且它还包含 null 节点,那我层序遍历的时候将下标也存储下来不就好了,每层循环开始的时候,该层最后一个非null节点下标与该层第一个非null的差,就是该层的宽度。用一个变量记录最大宽度,在每层遍历的时候不断更新。
题解
/**
* 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) {
const queue = [[root, 1n]];
let max = 0n;
while(queue.length) {
max = Math.max(queue.slice(-1)[0][1] - queue[0][1], max);
for(let i=0; i<queue.length; ++i) {
let [node, i] = queue.shift();
node.left && queue.push([node.left, i * 2]);
node.right && queue.push([node.right, i * 2 + 1n]);
}
}
return max;
};