题目
在二维平面上的 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 上着陆。
题解
典型的区间更新+最值查询的题目,用线段树就可以解决
java
class Solution {
int N = (int)1e9;
class Node {
// ls 和 rs 分别代表当前区间的左右子节点
Node ls, rs;
// val 代表当前区间的最大高度,add 为懒标记
int val, add;
}
Node root = new Node();
//更新区间的最值
void update(Node node, int lc, int rc, int l, int r, int v) {
if (l <= lc && rc <= r) {
node.add = v;
node.val = v;
return ;
}
pushdown(node);
int mid = lc + rc >> 1;
if (l <= mid) update(node.ls, lc, mid, l, r, v);
if (r > mid) update(node.rs, mid + 1, rc, l, r, v);
pushup(node);
}
//查询区间的最值
int query(Node node, int lc, int rc, int l, int r) {
if (l <= lc && rc <= r) return node.val;
pushdown(node);
int mid = lc + rc >> 1, ans = 0;
if (l <= mid) ans = query(node.ls, lc, mid, l, r);
if (r > mid) ans = Math.max(ans, query(node.rs, mid + 1, rc, l, r));
return ans;
}
//lazy tag下放
void pushdown(Node node) {
if (node.ls == null) node.ls = new Node();
if (node.rs == null) node.rs = new Node();
if (node.add == 0) return ;
node.ls.add = node.add; node.rs.add = node.add;
node.ls.val = node.add; node.rs.val = node.add;
node.add = 0;
}
//更新区间的最值
void pushup(Node node) {
node.val = Math.max(node.ls.val, node.rs.val);
}
public List<Integer> fallingSquares(int[][] ps) {
List<Integer> ans = new ArrayList<>();
for (int[] info : ps) {
int x = info[0];
h = info[1];
//查询当前区间的高度
cur = query(root, 0, N, x, x + h - 1);
//当前区间的高度+当前矩形的高度
update(root, 0, N, x, x + h - 1, cur + h);
ans.add(root.val);
}
return ans;
}
}