二叉树最大宽度
难度:
标签:
题目描述
给你一棵二叉树的根节点 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
代码结果
运行时间: 28 ms, 内存: 17.4 MB
// Java Stream solution
// 思路:使用广度优先搜索 (BFS) 遍历树的每一层。使用列表保存每层的节点和位置,然后使用stream求最大宽度。
import java.util.*;
public class Solution {
public int widthOfBinaryTree(TreeNode root) {
if (root == null) return 0;
int maxWidth = 0;
Queue<Pair<TreeNode, Integer>> queue = new LinkedList<>();
queue.offer(new Pair<>(root, 0));
while (!queue.isEmpty()) {
int size = queue.size();
int min = queue.peek().getValue();
List<Integer> positions = new ArrayList<>();
for (int i = 0; i < size; i++) {
Pair<TreeNode, Integer> pair = queue.poll();
TreeNode node = pair.getKey();
int curId = pair.getValue() - min;
positions.add(curId);
if (node.left != null) queue.offer(new Pair<>(node.left, curId * 2 + 1));
if (node.right != null) queue.offer(new Pair<>(node.right, curId * 2 + 2));
}
maxWidth = Math.max(maxWidth, positions.stream().max(Integer::compare).orElse(0) - positions.stream().min(Integer::compare).orElse(0) + 1);
}
return maxWidth;
}
}
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) { this.key = key; this.value = value; }
public K getKey() { return key; }
public V getValue() { return value; }
}
解释
方法:
这个题解使用了BFS的思路来解决二叉树最大宽度的问题。通过给每个节点标记唯一的索引值,可以计算出每一层的宽度。索引值的计算方式是:左子节点的索引值为父节点索引值的2倍,右子节点的索引值为父节点索引值的2倍加1。在BFS遍历的过程中,记录每一层最左边和最右边节点的索引值之差再加1,就可以得到该层的宽度。最后返回所有层宽度的最大值即可。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在BFS遍历中,如果某一层全部节点都是null,如何处理这种情况以准确计算宽度?
▷🦆
为什么选择使用BFS而不是DFS进行这个问题的宽度计算?BFS和DFS在这个问题上有什么本质的不同?
▷🦆
在计算索引时,是否有可能出现整数溢出的问题,尤其是在非常深的二叉树中?
▷🦆
在更新最大宽度时,使用了`arr[-1][1] - arr[0][1] + 1`,这种计算方式是否考虑了所有边界情况,比如只有一个节点的层?
▷