Skip to content

Commit ee8b637

Browse files
committed
407.接雨水II,优先级队列
1 parent 217a393 commit ee8b637

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

leetcode_Java/DoneTitle.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
394. 字符串解码
107107
402. 移掉 K 位数字
108108
406. 根据身高重建队列
109+
407. 接雨水 II
109110
415. 字符串相加
110111
416. 分割等和子集
111112
437. 路径总和

leetcode_Java/DoneType.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
232. 用栈实现队列
131131
316. 去除重复字母(单调递增栈)
132132
402. 移掉 K 位数字(单调递增栈)
133+
407. 接雨水 II(优先级队列)
133134
496. 下一个更大元素 I(单调递减栈)
134135
503. 下一个更大元素 II(单调递减栈)
135136
739. 每日温度(单调递减栈)

leetcode_Java/Solution0407.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// 407. 接雨水 II
2+
3+
4+
/*
5+
优先级队列:外圈到内圈访问,逐渐缩小圈
6+
1、使用优先级队列存放外圈柱子三元组,即横坐标、纵坐标、高度,升序排序。因为木桶原理,内圈柱子能灌多少水取决于外圈最低柱子的高度
7+
访问数组标记柱子是否访问过,访问过则跳过
8+
2、初始化,将外圈柱子三元组存入队列,并标记已访问
9+
3、当队列不为空时,队列弹出元素为外圈最低柱子,遍历访问最低柱子的上下左右四个方向的柱子。四个方向的作用在于外圈有四个边界,各取所需访问到内圈柱子。
10+
方向数组把上下左右四个坐标压缩成一维数组,灵活获取坐标
11+
4、因为外圈都被访问了,如果坐标有效,则说明柱子在圈内,所以如果被访问的柱子 坐标有效并且未访问,
12+
那么再判断外圈最低柱子与圈内柱子的高度差,如果高度差大于0,说明圈内柱子可以灌水体积为高度差,否则不能灌水
13+
5、被访问过的内圈柱子将作为新的外圈柱子,加入到队列中,高度是外圈柱子与内圈柱子取较高者,并标记已访问
14+
*/
15+
class Solution {
16+
public int trapRainWater(int[][] heightMap) {
17+
int m = heightMap.length, n = heightMap[0].length;
18+
boolean[][] visited = new boolean[m][n];
19+
PriorityQueue<int[]> queue = new PriorityQueue<>((o1, o2) -> o1[2] - o2[2]);
20+
for (int i = 0; i < m; i++) {
21+
for (int j = 0; j < n; j++) {
22+
if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
23+
queue.offer(new int[] {i, j, heightMap[i][j]});
24+
visited[i][j] = true;
25+
}
26+
}
27+
}
28+
int res = 0;
29+
int[] dirs = {0, -1, 0, 1, 0};
30+
while (!queue.isEmpty()) {
31+
int[] minSide = queue.poll();
32+
for (int k = 0; k < 4; k++) {
33+
int x = minSide[0] + dirs[k];
34+
int y = minSide[1] + dirs[k + 1];
35+
if (x >= 0 && x < m && y >= 0 && y < n && !visited[x][y]) {
36+
int heighDiff = minSide[2] - heightMap[x][y];
37+
if (heighDiff > 0) {
38+
res += heighDiff;
39+
}
40+
queue.offer(new int[] {x, y, Math.max(minSide[2], heightMap[x][y])});
41+
visited[x][y] = true;
42+
}
43+
}
44+
}
45+
return res;
46+
}
47+
}

0 commit comments

Comments
 (0)