LeetCode 题解工作台
掉落的方块
在二维平面上的 x 轴上,放置着一些方块。 给你一个二维整数数组 positions ,其中 positions[i] = [left i , sideLength i ] 表示:第 i 个方块边长为 sideLength i ,其左侧边与 x 轴上坐标点 left i 对齐。 每个方块都从一个比目…
3
题型
5
代码语言
3
相关题
当前训练重点
困难 · 数组·结合·segment·树
答案摘要
根据题目描述,我们需要维护一个区间集合,支持区间的修改和查询操作。这种情况下,我们可以使用线段树来解决。 线段树将整个区间分割为多个不连续的子区间,子区间的数量不超过 ,其中 是区间的长度。更新某个元素的值,只需要更新 个区间,并且这些区间都包含在一个包含该元素的大区间内。区间修改时,需要使用懒标记保证效率。
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 数组·结合·segment·树 题型思路
题目描述
在二维平面上的 x 轴上,放置着一些方块。
给你一个二维整数数组 positions ,其中 positions[i] = [lefti, sideLengthi] 表示:第 i 个方块边长为 sideLengthi ,其左侧边与 x 轴上坐标点 lefti 对齐。
每个方块都从一个比目前所有的落地方块更高的高度掉落而下。方块沿 y 轴负方向下落,直到着陆到 另一个正方形的顶边 或者是 x 轴上 。一个方块仅仅是擦过另一个方块的左侧边或右侧边不算着陆。一旦着陆,它就会固定在原地,无法移动。
在每个方块掉落后,你必须记录目前所有已经落稳的 方块堆叠的最高高度 。
返回一个整数数组 ans ,其中 ans[i] 表示在第 i 块方块掉落后堆叠的最高高度。
示例 1:
输入:positions = [[1,2],[2,3],[6,1]] 输出:[2,5,5] 解释: 第 1 个方块掉落后,最高的堆叠由方块 1 组成,堆叠的最高高度为 2 。 第 2 个方块掉落后,最高的堆叠由方块 1 和 2 组成,堆叠的最高高度为 5 。 第 3 个方块掉落后,最高的堆叠仍然由方块 1 和 2 组成,堆叠的最高高度为 5 。 因此,返回 [2, 5, 5] 作为答案。
示例 2:
输入:positions = [[100,100],[200,100]] 输出:[100,100] 解释: 第 1 个方块掉落后,最高的堆叠由方块 1 组成,堆叠的最高高度为 100 。 第 2 个方块掉落后,最高的堆叠可以由方块 1 组成也可以由方块 2 组成,堆叠的最高高度为 100 。 因此,返回 [100, 100] 作为答案。 注意,方块 2 擦过方块 1 的右侧边,但不会算作在方块 1 上着陆。
提示:
1 <= positions.length <= 10001 <= lefti <= 1081 <= sideLengthi <= 106
解题思路
方法一:线段树
根据题目描述,我们需要维护一个区间集合,支持区间的修改和查询操作。这种情况下,我们可以使用线段树来解决。
线段树将整个区间分割为多个不连续的子区间,子区间的数量不超过 ,其中 是区间的长度。更新某个元素的值,只需要更新 个区间,并且这些区间都包含在一个包含该元素的大区间内。区间修改时,需要使用懒标记保证效率。
- 线段树的每个节点代表一个区间;
- 线段树具有唯一的根节点,代表的区间是整个统计范围,如 ;
- 线段树的每个叶子节点代表一个长度为 1 的元区间 ;
- 对于每个内部节点 ,它的左儿子是 ,右儿子是 , 其中 ;
对于本题,线段树节点维护的信息有:
- 区间中方块的最大高度
- 懒标记
另外,由于数轴范围很大,达到 ,因此我们采用动态开点。
时间复杂度方面,每次查询和修改的时间复杂度为 ,总时间复杂度为 。空间复杂度为 。
class Node:
def __init__(self, l, r):
self.left = None
self.right = None
self.l = l
self.r = r
self.mid = (l + r) >> 1
self.v = 0
self.add = 0
class SegmentTree:
def __init__(self):
self.root = Node(1, int(1e9))
def modify(self, l, r, v, node=None):
if l > r:
return
if node is None:
node = self.root
if node.l >= l and node.r <= r:
node.v = v
node.add = v
return
self.pushdown(node)
if l <= node.mid:
self.modify(l, r, v, node.left)
if r > node.mid:
self.modify(l, r, v, node.right)
self.pushup(node)
def query(self, l, r, node=None):
if l > r:
return 0
if node is None:
node = self.root
if node.l >= l and node.r <= r:
return node.v
self.pushdown(node)
v = 0
if l <= node.mid:
v = max(v, self.query(l, r, node.left))
if r > node.mid:
v = max(v, self.query(l, r, node.right))
return v
def pushup(self, node):
node.v = max(node.left.v, node.right.v)
def pushdown(self, node):
if node.left is None:
node.left = Node(node.l, node.mid)
if node.right is None:
node.right = Node(node.mid + 1, node.r)
if node.add:
node.left.v = node.add
node.right.v = node.add
node.left.add = node.add
node.right.add = node.add
node.add = 0
class Solution:
def fallingSquares(self, positions: List[List[int]]) -> List[int]:
ans = []
mx = 0
tree = SegmentTree()
for l, w in positions:
r = l + w - 1
h = tree.query(l, r) + w
mx = max(mx, h)
ans.append(mx)
tree.modify(l, r, h)
return ans
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | complexity is O(N log N) because each square involves a log N query and update on the segment tree across N squares. Space complexity is O(N) for storing the compressed coordinates and segment tree nodes. |
| 空间 | O(N) |
面试官常问的追问
外企场景- question_mark
Check if candidates handle very large X coordinates efficiently.
- question_mark
Look for proper use of range maximum queries using a segment tree or ordered set.
- question_mark
Watch for mistakes in determining whether squares actually stack or just touch sides.
常见陷阱
外企场景- error
Failing to compress coordinates, causing memory overflow for large lefti values.
- error
Mistaking side contact for stacking, resulting in incorrect height calculation.
- error
Updating heights incorrectly across overlapping intervals, which produces wrong maximum heights.
进阶变体
外企场景- arrow_right_alt
Falling rectangles instead of squares, where width varies for each drop.
- arrow_right_alt
Allowing squares to slide horizontally if they touch a side, introducing physics-based landing rules.
- arrow_right_alt
Computing total area covered by all stacked squares after each drop instead of just maximum height.