接雨水(栈、数组)
定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
提示:
- 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]);
}
俄罗斯套娃信封问题(数组、二分查找)
给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。 当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。 请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。 注意:不允许旋转信封。 示例 1: 输入:envelopes = [[5,4],[6,4],[6,7],[2,3]] 输出:3 解释:最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。 示例 2: 输入:envelopes = [[1,1],[1,1],[1,1]] 输出: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<>();
lastHeight.add(envelopes[0][1]);
for (int i = 1; i < n; i++) {
int h = envelopes[i][1];
if (h > lastHeight.get(lastHeight.size() - 1))
lastHeight.add(h);
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();
}
}
完美矩形(数组、扫描线)
我们有 N 个与坐标轴对齐的矩形, 其中 N > 0, 判断它们是否能精确地覆盖一个矩形区域。
每个矩形用左下角的点和右上角的点的坐标来表示。例如, 一个单位正方形可以表示为 [1,1,2,2]。 ( 左下角的点的坐标为 (1, 1) 以及右上角的点的坐标为 (2, 2) )。
示例 1:
rectangles = [
[1,1,3,3],
[3,1,4,2],
[3,2,4,4],
[1,3,2,4],
[2,3,3,4] ]
返回 true。5个矩形一起可以精确地覆盖一个矩形区域。
示例 2:
rectangles = [
[1,1,2,3],
[1,3,2,4],
[3,1,4,2],
[3,2,4,4] ]
返回 false。两个矩形之间有间隔,无法覆盖成一个矩形。
示例 3:
rectangles = [
[1,1,3,3],
[3,1,4,2],
[1,3,2,4],
[3,2,4,4] ]
返回 false。图形顶端留有间隔,无法覆盖成一个矩形。
示例 4:
rectangles = [
[1,1,3,3],
[3,1,4,2],
[1,3,2,4],
[2,2,4,4] ]
返回 false。因为中间有相交区域,虽然形成了矩形,但不是精确覆盖。
解答:
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))
set.add(lt);
else
set.remove(lt);
if (!set.contains(lb))
set.add(lb);
else
set.remove(lb);
if (!set.contains(rt))
set.add(rt);
else
set.remove(rt);
if (!set.contains(rb))
set.add(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;
}
}
本文内容到此结束了, 如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。 如有错误❌疑问💬欢迎各位大佬指出。 主页:共饮一杯无的博客汇总👨💻
保持热爱,奔赴下一场山海。🏃🏃🏃