Skip to content

Commit 7081402

Browse files
committed
feat: add solutions to lc problem: No.0407
No.0407.Trapping Rain Water II
1 parent 713a085 commit 7081402

File tree

6 files changed

+303
-58
lines changed

6 files changed

+303
-58
lines changed

solution/0400-0499/0407.Trapping Rain Water II/README.md

+108-19
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@
4646

4747
<!-- 这里可写通用的实现逻辑 -->
4848

49+
**方法一:优先队列(小根堆)**
50+
51+
接雨水问题的变种,由于矩阵的边界上的高度是确定的,因此可以将矩阵的边界上的高度加入优先队列,然后从优先队列中取出最小的高度,然后将其四周的高度与其比较,如果四周的高度小于当前高度,则可以接雨水,接雨水的体积为当前高度减去四周的高度,然后将较大的高度加入优先队列,重复上述过程,直到优先队列为空。
52+
53+
时间复杂度 $O(m \times n \times \log (m \times n))$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数。
54+
4955
<!-- tabs:start -->
5056

5157
### **Python3**
@@ -63,17 +69,16 @@ class Solution:
6369
if i == 0 or i == m - 1 or j == 0 or j == n - 1:
6470
heappush(pq, (heightMap[i][j], i, j))
6571
vis[i][j] = True
66-
6772
ans = 0
73+
dirs = (-1, 0, 1, 0, -1)
6874
while pq:
69-
e = heappop(pq)
70-
for x, y in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
71-
i, j = e[1] + x, e[2] + y
72-
if i >= 0 and i < m and j >= 0 and j < n and not vis[i][j]:
73-
if heightMap[i][j] < e[0]:
74-
ans += e[0] - heightMap[i][j]
75-
vis[i][j] = True
76-
heappush(pq, (max(heightMap[i][j], e[0]), i, j))
75+
h, i, j = heappop(pq)
76+
for a, b in pairwise(dirs):
77+
x, y = i + a, j + b
78+
if x >= 0 and x < m and y >= 0 and y < n and not vis[x][y]:
79+
ans += max(0, h - heightMap[x][y])
80+
vis[x][y] = True
81+
heappush(pq, (max(h, heightMap[x][y]), x, y))
7782
return ans
7883
```
7984

@@ -86,7 +91,7 @@ class Solution {
8691
public int trapRainWater(int[][] heightMap) {
8792
int m = heightMap.length, n = heightMap[0].length;
8893
boolean[][] vis = new boolean[m][n];
89-
PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[0] - o2[0]);
94+
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
9095
for (int i = 0; i < m; ++i) {
9196
for (int j = 0; j < n; ++j) {
9297
if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
@@ -96,23 +101,107 @@ class Solution {
96101
}
97102
}
98103
int ans = 0;
99-
int[][] dirs = new int[][] {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
104+
int[] dirs = {-1, 0, 1, 0, -1};
100105
while (!pq.isEmpty()) {
101-
int[] e = pq.poll();
102-
for (int[] d : dirs) {
103-
int i = e[1] + d[0], j = e[2] + d[1];
104-
if (i >= 0 && i < m && j >= 0 && j < n && !vis[i][j]) {
105-
if (heightMap[i][j] < e[0]) {
106-
ans += e[0] - heightMap[i][j];
107-
}
106+
var p = pq.poll();
107+
for (int k = 0; k < 4; ++k) {
108+
int x = p[1] + dirs[k], y = p[2] + dirs[k + 1];
109+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y]) {
110+
ans += Math.max(0, p[0] - heightMap[x][y]);
111+
vis[x][y] = true;
112+
pq.offer(new int[] {Math.max(p[0], heightMap[x][y]), x, y});
113+
}
114+
}
115+
}
116+
return ans;
117+
}
118+
}
119+
```
120+
121+
### **C++**
122+
123+
```cpp
124+
class Solution {
125+
public:
126+
int trapRainWater(vector<vector<int>>& heightMap) {
127+
using tii = tuple<int, int, int>;
128+
priority_queue<tii, vector<tii>, greater<tii>> pq;
129+
int m = heightMap.size(), n = heightMap[0].size();
130+
bool vis[m][n];
131+
memset(vis, 0, sizeof vis);
132+
for (int i = 0; i < m; ++i) {
133+
for (int j = 0; j < n; ++j) {
134+
if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
135+
pq.emplace(heightMap[i][j], i, j);
108136
vis[i][j] = true;
109-
pq.offer(new int[] {Math.max(heightMap[i][j], e[0]), i, j});
137+
}
138+
}
139+
}
140+
int ans = 0;
141+
int dirs[5] = {-1, 0, 1, 0, -1};
142+
while (!pq.empty()) {
143+
auto [h, i, j] = pq.top();
144+
pq.pop();
145+
for (int k = 0; k < 4; ++k) {
146+
int x = i + dirs[k], y = j + dirs[k + 1];
147+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y]) {
148+
ans += max(0, h - heightMap[x][y]);
149+
vis[x][y] = true;
150+
pq.emplace(max(heightMap[x][y], h), x, y);
110151
}
111152
}
112153
}
113154
return ans;
114155
}
156+
};
157+
```
158+
159+
### **Go**
160+
161+
```go
162+
func trapRainWater(heightMap [][]int) (ans int) {
163+
m, n := len(heightMap), len(heightMap[0])
164+
pq := hp{}
165+
vis := make([][]bool, m)
166+
for i, row := range heightMap {
167+
vis[i] = make([]bool, n)
168+
for j, v := range row {
169+
if i == 0 || i == m-1 || j == 0 || j == n-1 {
170+
heap.Push(&pq, tuple{v, i, j})
171+
vis[i][j] = true
172+
}
173+
}
174+
}
175+
dirs := []int{-1, 0, 1, 0, -1}
176+
for len(pq) > 0 {
177+
p := heap.Pop(&pq).(tuple)
178+
for k := 0; k < 4; k++ {
179+
x, y := p.i+dirs[k], p.j+dirs[k+1]
180+
if x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] {
181+
ans += max(0, p.v-heightMap[x][y])
182+
vis[x][y] = true
183+
heap.Push(&pq, tuple{max(p.v, heightMap[x][y]), x, y})
184+
}
185+
}
186+
}
187+
return
115188
}
189+
190+
func max(a, b int) int {
191+
if a > b {
192+
return a
193+
}
194+
return b
195+
}
196+
197+
type tuple struct{ v, i, j int }
198+
type hp []tuple
199+
200+
func (h hp) Len() int { return len(h) }
201+
func (h hp) Less(i, j int) bool { return h[i].v < h[j].v }
202+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
203+
func (h *hp) Push(v interface{}) { *h = append(*h, v.(tuple)) }
204+
func (h *hp) Pop() interface{} { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
116205
```
117206

118207
### **...**

solution/0400-0499/0407.Trapping Rain Water II/README_EN.md

+102-19
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,16 @@ class Solution:
5151
if i == 0 or i == m - 1 or j == 0 or j == n - 1:
5252
heappush(pq, (heightMap[i][j], i, j))
5353
vis[i][j] = True
54-
5554
ans = 0
55+
dirs = (-1, 0, 1, 0, -1)
5656
while pq:
57-
e = heappop(pq)
58-
for x, y in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
59-
i, j = e[1] + x, e[2] + y
60-
if i >= 0 and i < m and j >= 0 and j < n and not vis[i][j]:
61-
if heightMap[i][j] < e[0]:
62-
ans += e[0] - heightMap[i][j]
63-
vis[i][j] = True
64-
heappush(pq, (max(heightMap[i][j], e[0]), i, j))
57+
h, i, j = heappop(pq)
58+
for a, b in pairwise(dirs):
59+
x, y = i + a, j + b
60+
if x >= 0 and x < m and y >= 0 and y < n and not vis[x][y]:
61+
ans += max(0, h - heightMap[x][y])
62+
vis[x][y] = True
63+
heappush(pq, (max(h, heightMap[x][y]), x, y))
6564
return ans
6665
```
6766

@@ -72,7 +71,7 @@ class Solution {
7271
public int trapRainWater(int[][] heightMap) {
7372
int m = heightMap.length, n = heightMap[0].length;
7473
boolean[][] vis = new boolean[m][n];
75-
PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[0] - o2[0]);
74+
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]);
7675
for (int i = 0; i < m; ++i) {
7776
for (int j = 0; j < n; ++j) {
7877
if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
@@ -82,23 +81,107 @@ class Solution {
8281
}
8382
}
8483
int ans = 0;
85-
int[][] dirs = new int[][] {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
84+
int[] dirs = {-1, 0, 1, 0, -1};
8685
while (!pq.isEmpty()) {
87-
int[] e = pq.poll();
88-
for (int[] d : dirs) {
89-
int i = e[1] + d[0], j = e[2] + d[1];
90-
if (i >= 0 && i < m && j >= 0 && j < n && !vis[i][j]) {
91-
if (heightMap[i][j] < e[0]) {
92-
ans += e[0] - heightMap[i][j];
93-
}
86+
var p = pq.poll();
87+
for (int k = 0; k < 4; ++k) {
88+
int x = p[1] + dirs[k], y = p[2] + dirs[k + 1];
89+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y]) {
90+
ans += Math.max(0, p[0] - heightMap[x][y]);
91+
vis[x][y] = true;
92+
pq.offer(new int[] {Math.max(p[0], heightMap[x][y]), x, y});
93+
}
94+
}
95+
}
96+
return ans;
97+
}
98+
}
99+
```
100+
101+
### **C++**
102+
103+
```cpp
104+
class Solution {
105+
public:
106+
int trapRainWater(vector<vector<int>>& heightMap) {
107+
using tii = tuple<int, int, int>;
108+
priority_queue<tii, vector<tii>, greater<tii>> pq;
109+
int m = heightMap.size(), n = heightMap[0].size();
110+
bool vis[m][n];
111+
memset(vis, 0, sizeof vis);
112+
for (int i = 0; i < m; ++i) {
113+
for (int j = 0; j < n; ++j) {
114+
if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
115+
pq.emplace(heightMap[i][j], i, j);
94116
vis[i][j] = true;
95-
pq.offer(new int[] {Math.max(heightMap[i][j], e[0]), i, j});
117+
}
118+
}
119+
}
120+
int ans = 0;
121+
int dirs[5] = {-1, 0, 1, 0, -1};
122+
while (!pq.empty()) {
123+
auto [h, i, j] = pq.top();
124+
pq.pop();
125+
for (int k = 0; k < 4; ++k) {
126+
int x = i + dirs[k], y = j + dirs[k + 1];
127+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y]) {
128+
ans += max(0, h - heightMap[x][y]);
129+
vis[x][y] = true;
130+
pq.emplace(max(heightMap[x][y], h), x, y);
96131
}
97132
}
98133
}
99134
return ans;
100135
}
136+
};
137+
```
138+
139+
### **Go**
140+
141+
```go
142+
func trapRainWater(heightMap [][]int) (ans int) {
143+
m, n := len(heightMap), len(heightMap[0])
144+
pq := hp{}
145+
vis := make([][]bool, m)
146+
for i, row := range heightMap {
147+
vis[i] = make([]bool, n)
148+
for j, v := range row {
149+
if i == 0 || i == m-1 || j == 0 || j == n-1 {
150+
heap.Push(&pq, tuple{v, i, j})
151+
vis[i][j] = true
152+
}
153+
}
154+
}
155+
dirs := []int{-1, 0, 1, 0, -1}
156+
for len(pq) > 0 {
157+
p := heap.Pop(&pq).(tuple)
158+
for k := 0; k < 4; k++ {
159+
x, y := p.i+dirs[k], p.j+dirs[k+1]
160+
if x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] {
161+
ans += max(0, p.v-heightMap[x][y])
162+
vis[x][y] = true
163+
heap.Push(&pq, tuple{max(p.v, heightMap[x][y]), x, y})
164+
}
165+
}
166+
}
167+
return
168+
}
169+
170+
func max(a, b int) int {
171+
if a > b {
172+
return a
173+
}
174+
return b
101175
}
176+
177+
type tuple struct{ v, i, j int }
178+
type hp []tuple
179+
180+
func (h hp) Len() int { return len(h) }
181+
func (h hp) Less(i, j int) bool { return h[i].v < h[j].v }
182+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
183+
func (h *hp) Push(v interface{}) { *h = append(*h, v.(tuple)) }
184+
func (h *hp) Pop() interface{} { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
102185
```
103186

104187
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Solution {
2+
public:
3+
int trapRainWater(vector<vector<int>>& heightMap) {
4+
using tii = tuple<int, int, int>;
5+
priority_queue<tii, vector<tii>, greater<tii>> pq;
6+
int m = heightMap.size(), n = heightMap[0].size();
7+
bool vis[m][n];
8+
memset(vis, 0, sizeof vis);
9+
for (int i = 0; i < m; ++i) {
10+
for (int j = 0; j < n; ++j) {
11+
if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
12+
pq.emplace(heightMap[i][j], i, j);
13+
vis[i][j] = true;
14+
}
15+
}
16+
}
17+
int ans = 0;
18+
int dirs[5] = {-1, 0, 1, 0, -1};
19+
while (!pq.empty()) {
20+
auto [h, i, j] = pq.top();
21+
pq.pop();
22+
for (int k = 0; k < 4; ++k) {
23+
int x = i + dirs[k], y = j + dirs[k + 1];
24+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y]) {
25+
ans += max(0, h - heightMap[x][y]);
26+
vis[x][y] = true;
27+
pq.emplace(max(heightMap[x][y], h), x, y);
28+
}
29+
}
30+
}
31+
return ans;
32+
}
33+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
func trapRainWater(heightMap [][]int) (ans int) {
2+
m, n := len(heightMap), len(heightMap[0])
3+
pq := hp{}
4+
vis := make([][]bool, m)
5+
for i, row := range heightMap {
6+
vis[i] = make([]bool, n)
7+
for j, v := range row {
8+
if i == 0 || i == m-1 || j == 0 || j == n-1 {
9+
heap.Push(&pq, tuple{v, i, j})
10+
vis[i][j] = true
11+
}
12+
}
13+
}
14+
dirs := []int{-1, 0, 1, 0, -1}
15+
for len(pq) > 0 {
16+
p := heap.Pop(&pq).(tuple)
17+
for k := 0; k < 4; k++ {
18+
x, y := p.i+dirs[k], p.j+dirs[k+1]
19+
if x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] {
20+
ans += max(0, p.v-heightMap[x][y])
21+
vis[x][y] = true
22+
heap.Push(&pq, tuple{max(p.v, heightMap[x][y]), x, y})
23+
}
24+
}
25+
}
26+
return
27+
}
28+
29+
func max(a, b int) int {
30+
if a > b {
31+
return a
32+
}
33+
return b
34+
}
35+
36+
type tuple struct{ v, i, j int }
37+
type hp []tuple
38+
39+
func (h hp) Len() int { return len(h) }
40+
func (h hp) Less(i, j int) bool { return h[i].v < h[j].v }
41+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
42+
func (h *hp) Push(v interface{}) { *h = append(*h, v.(tuple)) }
43+
func (h *hp) Pop() interface{} { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }

0 commit comments

Comments
 (0)