699 falling squares
class Solution {
private int MAXN = 2001;
private int[] arr = new int[MAXN * 4];
private int[] maxh = new int[MAXN * 4];
private int[] change = new int[MAXN * 4];
private boolean[] update = new boolean[MAXN * 4];
public List<Integer> fallingSquares(int[][] positions) {
List<Integer> ans = new ArrayList<>();
int n = reduce(positions);
int max = 0;
for (int[] position : positions) {
int l = search(arr, position[0], n);
int r = search(arr, position[0] + position[1] - 1, n);
int h = query(l, r, 1, n, 1);
h += position[1];
update(h, l, r, 1, n, 1);
max = Math.max(h, max);
ans.add(max);
}
return ans;
}
private void update(int val, int jobl, int jobr, int left, int right, int idx) {
if (left >= jobl && right <= jobr) {
lazy(val, idx);
return;
}
down(idx);
int mid = (left + right) / 2;
if (jobl <= mid) {
update(val, jobl, jobr, left, mid, idx*2);
}
if (jobr > mid) {
update(val, jobl, jobr, mid+1, right, idx*2+1);
}
maxh[idx] = Math.max(maxh[idx*2], maxh[idx*2+1]);
}
private void lazy(int val, int idx) {
update[idx] = true;
change[idx] = val;
maxh[idx] = val;
}
private void down(int idx) {
if (update[idx]) {
lazy(change[idx], idx*2);
lazy(change[idx], idx*2+1);
}
update[idx] = false;
}
private int query(int jobl, int jobr, int left, int right, int idx) {
if (left >= jobl && right <= jobr) {
return maxh[idx];
}
int mid = (left + right) / 2;
down(idx);
int h = 0;
if (jobl <= mid) {
h = Math.max(h, query(jobl, jobr, left, mid, idx*2));
}
if (jobr > mid) {
h = Math.max(h, query(jobl, jobr, mid+1, right, idx*2+1));
}
return h;
}
private int search(int[] arr, int val, int n) {
int l = 1;
int r = n;
while (l + 1 < r) {
int m = (l + r) / 2;
if (arr[m] == val) {
return m;
}
if (arr[m] > val) {
r = m;
} else {
l = m;
}
}
if (arr[l] == val) {
return l;
}
return r;
}
private int reduce(int[][] positions) {
int size = 1;
int n = 1;
// start from 1
for (int[] position : positions) {
arr[size++] = position[0];
arr[size++] = position[0] + position[1] - 1;
}
Arrays.sort(arr, 1, size);
for (int i = 1; i < size; i++) {
if (arr[n] != arr[i]) {
arr[++n] = arr[i];
}
}
return n;
}
}
注意几个函数
update -> down + up + lazy
query -> down
down -> lazy
如何将离散的数据变紧凑,将数据sort并去重之后用它们的index作为range和range内的坐标
同时注意区间是左闭右开,右边界坐标总是-1
Last updated