## 接雨水(栈、数组)

n 个非负整数表示每个宽度为 1 的柱子的高度图，计算按此排列的柱子，下雨之后能接多少雨水。

``````输入：height = [0,1,0,2,1,0,1,3,2,1,2,1]

``````

``````输入：height = [4,2,0,3,2,5]

``````

• n == height.length
• 0 <= n <= 3 * 104
• 0 <= height[i] <= 105

``````class Solution {
public int trap(int[] height) {
if (height == null)
return 0;
int len = height.length;
if (len == 0)
return 0;
int res = 0;
int[] left_max = new int[len];
int[] right_max = new int[len];
left_max[0] = height[0];

for (int i = 1; i < len; i++) {
left_max[i] = Math.max(height[i], left_max[i - 1]);
}
right_max[len - 1] = height[len - 1];

____________________;

for (int i = 1; i < len - 1; i++) {
res += Math.min(left_max[i], right_max[i]) - height[i];
}
return res;
}
}
``````

``````for (int i = len - 2; i >= 0; i--) {
right_max[i] = Math.max(height[i], right_max[i + 1]);
}
``````

## 俄罗斯套娃信封问题(数组、二分查找)

• 1 <= envelopes.length <= 5000
• envelopes[i].length == 2
• 1 <= wi, hi <= 104

``````class Solution {
public int maxEnvelopes(int[][] envelopes) {
int n = envelopes.length;
if (n == 0)
return 0;
Arrays.sort(envelopes, new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
if (a[0] != b[0])
return a[0] - b[0];
return b[1] - a[1];
}
});
List<Integer> lastHeight = new ArrayList<>();
for (int i = 1; i < n; i++) {
int h = envelopes[i][1];
if (h > lastHeight.get(lastHeight.size() - 1))
else {
int l = 0, r = lastHeight.size() - 1;
while (r > l) {
int m = (l + r) >> 1;
if (lastHeight.get(m) < h)
l = m + 1;
else
r = m;
}
lastHeight.set(l, h);
}
}
return lastHeight.size();
}
}
``````

## 完美矩形(数组、扫描线)

``````rectangles = [
[1,1,3,3],
[3,1,4,2],
[3,2,4,4],
[1,3,2,4],
[2,3,3,4] ]

``````

``````rectangles = [
[1,1,2,3],
[1,3,2,4],
[3,1,4,2],
[3,2,4,4] ]

``````

``````rectangles = [
[1,1,3,3],
[3,1,4,2],
[1,3,2,4],
[3,2,4,4] ]

``````

``````rectangles = [
[1,1,3,3],
[3,1,4,2],
[1,3,2,4],
[2,2,4,4] ]

``````

``````class Solution {
public boolean isRectangleCover(int[][] rectangles) {
int left = Integer.MAX_VALUE;
int right = Integer.MIN_VALUE;
int top = Integer.MIN_VALUE;
int bottom = Integer.MAX_VALUE;
int n = rectangles.length;
Set<String> set = new HashSet<>();
int sumArea = 0;
for (int i = 0; i < n; i++) {
left = Math.min(left, rectangles[i][0]);
bottom = Math.min(bottom, rectangles[i][1]);
right = Math.max(right, rectangles[i][2]);
top = Math.max(top, rectangles[i][3]);
sumArea += (rectangles[i][3] - rectangles[i][1]) * (rectangles[i][2] - rectangles[i][0]);
String lt = rectangles[i][0] + " " + rectangles[i][3];
String lb = rectangles[i][0] + " " + rectangles[i][1];
String rt = rectangles[i][2] + " " + rectangles[i][3];
String rb = rectangles[i][2] + " " + rectangles[i][1];
if (!set.contains(lt))
else
set.remove(lt);
if (!set.contains(lb))
else
set.remove(lb);
if (!set.contains(rt))
else
set.remove(rt);
if (!set.contains(rb))
else
set.remove(rb);
}
if (set.size() == 4 && set.contains(left + " " + top) && set.contains(left + " " + bottom)
&& set.contains(right + " " + bottom) && set.contains(right + " " + top)) {
return sumArea == (right - left) * (top - bottom);
}
return false;
}
}
``````