1. 问题分析与解法概述
LeetCode 699题"掉落的方块"是一个经典的区间合并与高度计算问题。题目描述如下:给定一系列方块的掉落位置和边长,每个方块会垂直落下并停靠在其他方块或地面上。我们需要实时记录每次方块落下后的最高高度。
1.1 问题核心分析
这个问题的核心在于如何高效地处理区间重叠和高度计算。每个方块可以用一个区间[left, right]表示,其中left是方块的左边界,right=left+sideLength。当新方块落下时,我们需要:
- 找出所有与新方块区间重叠的已有方块
- 计算这些重叠方块中的最大高度
- 新方块的高度=最大重叠高度+自身边长
- 更新全局最大高度
1.2 解法思路对比
针对这个问题,常见的解法有四种:
- 暴力模拟法:直接遍历所有已有方块检查重叠,时间复杂度O(n²)
- 有序集合优化法:使用TreeMap存储区间边界,时间复杂度O(n log n)
- 线段树法:使用线段树进行区间查询和更新,时间复杂度O(n log n)
- 优化模拟法:改进的暴力法,更易理解但时间复杂度仍为O(n²)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 暴力模拟法详解
2.1 实现思路
暴力模拟法是最直观的解决方案。我们维护一个列表存储所有已落下方块的区间和高度。对于每个新方块:
- 遍历所有已有方块,检查是否有区间重叠
- 找出重叠方块中的最大高度作为基础高度
- 新方块高度=基础高度+自身边长
- 更新全局最大高度
2.2 代码实现
java复制class Solution {
public List<Integer> fallingSquares(int[][] positions) {
List<Integer> res = new ArrayList<>();
// 存储每个区间的 [左边界, 右边界, 高度]
List<int[]> intervals = new ArrayList<>();
int maxHeight = 0;
for (int[] pos : positions) {
int left = pos[0];
int sideLength = pos[1];
int right = left + sideLength;
// 计算当前方块落下后的基础高度
int baseHeight = 0;
// 遍历已有的区间,找出当前方块下方最高的点
for (int[] interval : intervals) {
// 检查区间重叠
if (interval[0] < right && interval[1] > left) {
baseHeight = Math.max(baseHeight, interval[2]);
}
}
// 当前方块的高度 = 基础高度 + 自身边长
int currentHeight = baseHeight + sideLength;
// 将新区间加入
intervals.add(new int[]{left, right, currentHeight});
// 更新全局最大高度
maxHeight = Math.max(maxHeight, currentHeight);
res.add(maxHeight);
}
return res;
}
}
2.3 复杂度分析
- 时间复杂度:O(n²),因为对于每个新方块,都需要遍历所有已有方块检查重叠
- 空间复杂度:O(n),需要存储所有方块的区间信息
2.4 适用场景
暴力模拟法适合:
- 面试中快速实现
- 数据规模较小的情况(n≤1000)
- 需要简单直观的解决方案时
提示:虽然时间复杂度较高,但在LeetCode上对于小规模数据仍然可以通过
