携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
每日刷题 2022.08.27
- leetcode原题链接:leetcode.cn/problems/ma…
- 难度:中等
- 方法:广度优先遍历
题目
- 给你一棵二叉树的根节点 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) 。
提示
- 树中节点的数目范围是
[1, 3000] -100 <= Node.val <= 100
解题思路
- 根据题目含义:对于二叉树的每一层左节点(非空)和右节点(非空)之间的节点数(包含
null节点的个数),返回所有层中的最大宽度。 - 既然是最大宽度,那么使用层序遍历来一层一层的遍历,最后将每一层的宽度取一个最大值即可。那么还有一个问题:如果将
null节点的左右子节点也记录下来呢? - 于是就想到了满二叉树,将所有的
null节点都填充起来,对于每一层只记录左边(非空节点)和右边(非空节点)之间的差值长度。最终将每一层记录下的宽度作比较,获得最大宽度,返回即可。
AC代码
/**
* @param {TreeNode} root
* @return {number}
*/
var widthOfBinaryTree = function(root) {
let obj = {
id: 1 >>> 0,
node: root
}
let queue = [obj], maxWid = 0;
while(queue.length != 0) {
let len = queue.length, q = [], wid = queue[0].id;
for(let i = 0; i < len; i++) {
// 每一层需要得出一个值
let cur = queue[i], idx = cur.id;
// 仅仅只需要寻找下一层可以存放的节点,并更新id
if(cur.node.left != null) {
let o = {
id: (idx * 2) >>> 0,
node: cur.node.left
}
q.push(o);
}
if(cur.node.right != null) {
let o = {
id: (idx * 2 + 1) >>> 0,
node: cur.node.right
}
q.push(o);
}
}
maxWid = Math.max(maxWid, queue[len - 1].id - wid + 1);
queue = q;
}
return maxWid;
};