407.接雨水II
题目描述
思路:广度优先搜索
假定初始矩阵中的每个格子都装满了水,且高度均为maxHeight,其中maxHeight为矩阵中高度最高的格子。我们知道方块接水后的高度为water[i][j],它的求解公式与方法一样,方块(i, j)的接水后的高度为:
w
a
t
e
r
[
i
]
[
j
]
=
m
a
x
(
h
e
i
g
h
t
M
a
p
[
i
]
,
m
i
n
(
w
a
t
e
r
[
i
−
1
]
[
j
]
,
w
a
t
e
r
[
i
+
1
]
[
j
]
,
w
a
t
e
r
[
i
]
[
j
−
1
]
,
w
a
t
e
r
[
i
]
[
j
+
1
]
)
)
water[i][j] = max(heightMap[i], min(water[i-1][j], water[i+1][j], water[i][j-1], water[i][j+1]))
water[i][j]=max(heightMap[i],min(water[i−1][j],water[i+1][j],water[i][j−1],water[i][j+1])),而方块(i, j)实际接水的容量为water[i][j]-heightMap[i][j]。
假设每个方块(i, j)的接水后的高度均为water[i][j]=maxHeight,最外层的方块不能用于接水,所有的多余的水会从最外层的方块溢出,当前方块(i, j)的接水高度water[i][j]小于与之相邻的4个方块的接水高度时,则调整接水高度,将其相邻的四个方块的接水高度调整与(i, j)的高度保持一致,不断重复进行调整,直到所有的方块的接水高度不再有调整时即满足要求。
Java实现
class Solution {
public int trapRainWater(int[][] heightMap) {
int m = heightMap.length;
int n = heightMap[0].length;
int[] dirs = {-1, 0, 1, 0, -1};
int maxHeight = 0;
for (int i=0; i < m; ++i) {
for (int j=0; j < n; ++j) {
maxHeight = Math.max(maxHeight, heightMap[i][j]);
}
}
int[][] water = new int[m][n];
for (int i=0; i < m; ++i) {
for (int j=0; j < n; ++j) {
water[i][j] = maxHeight;
}
}
Queue<int[]> qu = new LinkedList<>();
for (int i=0; i < m; ++i) {
for (int j=0; j < n; ++j) {
if (i == 0 || i == m-1 || j == 0 || j == n-1) {
if (water[i][j] > heightMap[i][j]) {
water[i][j] = heightMap[i][j];
qu.offer(new int[]{i ,j});
}
}
}
}
while (!qu.isEmpty()) {
int[] cur = qu.poll();
int x = cur[0];
int y = cur[1];
for (int i=0; i < 4; ++i) {
int nx = x + dirs[i];
int ny = y + dirs[i+1];
if (nx < 0 || nx >= m || ny < 0 || ny >= n) {
continue;
}
if (water[x][y] < water[nx][ny] && water[nx][ny] > heightMap[nx][ny]) {
water[nx][ny] = Math.max(water[x][y], heightMap[nx][ny]);
qu.offer(new int[]{nx, ny});
}
}
}
int res = 0;
for (int i = 0; i < m ; ++i) {
for (int j = 0; j < n; ++j) {
res += water[i][j] - heightMap[i][j];
}
}
return res;
}
}
Python实现
class Solution:
def trapRainWater(self, heightMap: List[List[int]]) -> int:
m, n = len(heightMap), len(heightMap[0])
maxHeight = max(max(row) for row in heightMap)
water = [[maxHeight for i in range(n)] for j in range(m)]
dirs = [-1, 0, 1, 0, -1]
qu = []
for i in range(m):
for j in range(n):
if i == 0 or i == m-1 or j == 0 or j == n-1:
if water[i][j] > heightMap[i][j]:
water[i][j] = heightMap[i][j]
qu.append([i, j])
while len(qu) > 0:
[x, y] = qu.pop(0)
for i in range(4):
nx, ny = x + dirs[i], y + dirs[i+1]
if nx < 0 or nx >= m or ny < 0 or ny >= n:
continue
if water[x][y] < water[nx][ny] and water[nx][ny] > heightMap[nx][ny]:
water[nx][ny] = max(water[x][y], heightMap[nx][ny])
qu.append([nx, ny])
ans = 0
for i in range(m):
for j in range(n):
ans = ans + water[i][j] - heightMap[i][j]
return ans