407. 接雨水 II
给你一个 m x n
的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。
示例 1:
输入: heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]] 输出: 4 解释: 下雨后,雨水将会被上图蓝色的方块中。总的接雨水量为1+2+1=4。
示例 2:
输入: heightMap = [[3,3,3,3,3],[3,2,2,2,3],[3,2,1,2,3],[3,2,2,2,3],[3,3,3,3,3]] 输出: 10
提示:
m == heightMap.length
n == heightMap[i].length
1 <= m, n <= 200
0 <= heightMap[i][j] <= 2 * 104
相似题目
原站题解
cpp 解法, 执行用时: 48 ms, 内存消耗: 15.2 MB, 提交时间: 2023-09-19 16:53:10
class Solution { public: int trapRainWater(vector<vector<int>>& heightMap) { int m = heightMap.size(), n = heightMap[0].size(); int maxHeight = 0; int dirs[] = {-1, 0, 1, 0, -1}; for (int i = 0; i < m; ++i) { maxHeight = max(maxHeight, *max_element(heightMap[i].begin(), heightMap[i].end())); } vector<vector<int>> water(m, vector<int>(n, maxHeight)); queue<pair<int,int>> qu; 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.push(make_pair(i, j)); } } } } while (!qu.empty()) { int x = qu.front().first, y = qu.front().second; qu.pop(); for (int i = 0; i < 4; ++i) { int nx = x + dirs[i], 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] = max(water[x][y], heightMap[nx][ny]); qu.push(make_pair(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; } };
java 解法, 执行用时: 16 ms, 内存消耗: 43.8 MB, 提交时间: 2023-09-19 16:52:54
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[] curr = qu.poll(); int x = curr[0]; int y = curr[1]; for (int i = 0; i < 4; ++i) { int nx = x + dirs[i], 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; } }
python3 解法, 执行用时: 400 ms, 内存消耗: 18.2 MB, 提交时间: 2023-09-19 16:52:38
# bfs 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 _ in range(n)] for _ 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
javascript 解法, 执行用时: 120 ms, 内存消耗: 48.7 MB, 提交时间: 2023-09-19 16:52:18
/** * @param {number[][]} heightMap * @return {number} */ // bfs var trapRainWater = function(heightMap) { const m = heightMap.length; const n = heightMap[0].length; const dirs = [-1, 0, 1, 0, -1]; let maxHeight = 0; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { maxHeight = Math.max(maxHeight, heightMap[i][j]); } } const water = new Array(m).fill(0).map(() => new Array(n).fill(0)); for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j){ water[i][j] = maxHeight; } } const qu = []; for (let i = 0; i < m; ++i) { for (let 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.push([i, j]); } } } } while (qu.length) { const curr = qu.shift(); const x = curr[0]; const y = curr[1]; for (let i = 0; i < 4; ++i) { const nx = x + dirs[i], 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.push([nx, ny]); } } } let res = 0; for (let i = 0; i < m; ++i) { for (let j = 0; j < n; ++j) { res += water[i][j] - heightMap[i][j]; } } return res; };
golang 解法, 执行用时: 40 ms, 内存消耗: 6.8 MB, 提交时间: 2023-09-19 16:51:54
// dfs func trapRainWater(heightMap [][]int) (ans int) { m, n := len(heightMap), len(heightMap[0]) maxHeight := 0 for _, row := range heightMap { for _, h := range row { maxHeight = max(maxHeight, h) } } water := make([][]int, m) for i := range water { water[i] = make([]int, n) for j := range water[i] { water[i][j] = maxHeight } } type pair struct{ x, y int } q := []pair{} for i, row := range heightMap { for j, h := range row { if (i == 0 || i == m-1 || j == 0 || j == n-1) && h < water[i][j] { water[i][j] = h q = append(q, pair{i, j}) } } } dirs := []int{-1, 0, 1, 0, -1} for len(q) > 0 { p := q[0] q = q[1:] x, y := p.x, p.y for i := 0; i < 4; i++ { nx, ny := x+dirs[i], y+dirs[i+1] if 0 <= nx && nx < m && 0 <= ny && ny < n && water[nx][ny] > water[x][y] && water[nx][ny] > heightMap[nx][ny] { water[nx][ny] = max(water[x][y], heightMap[nx][ny]) q = append(q, pair{nx, ny}) } } } for i, row := range heightMap { for j, h := range row { ans += water[i][j] - h } } return } func max(a, b int) int { if b > a { return b } return a }
golang 解法, 执行用时: 28 ms, 内存消耗: 8.6 MB, 提交时间: 2023-09-19 16:51:05
func trapRainWater(heightMap [][]int) (ans int) { m, n := len(heightMap), len(heightMap[0]) if m <= 2 || n <= 2 { return } vis := make([][]bool, m) for i := range vis { vis[i] = make([]bool, n) } h := &hp{} for i, row := range heightMap { for j, v := range row { if i == 0 || i == m-1 || j == 0 || j == n-1 { heap.Push(h, cell{v, i, j}) vis[i][j] = true } } } dirs := []int{-1, 0, 1, 0, -1} for h.Len() > 0 { cur := heap.Pop(h).(cell) for k := 0; k < 4; k++ { nx, ny := cur.x+dirs[k], cur.y+dirs[k+1] if 0 <= nx && nx < m && 0 <= ny && ny < n && !vis[nx][ny] { if heightMap[nx][ny] < cur.h { ans += cur.h - heightMap[nx][ny] } vis[nx][ny] = true heap.Push(h, cell{max(heightMap[nx][ny], cur.h), nx, ny}) } } } return } type cell struct{ h, x, y int } type hp []cell func (h hp) Len() int { return len(h) } func (h hp) Less(i, j int) bool { return h[i].h < h[j].h } func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *hp) Push(v interface{}) { *h = append(*h, v.(cell)) } func (h *hp) Pop() interface{} { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v } func max(a, b int) int { if b > a { return b } return a }
python3 解法, 执行用时: 236 ms, 内存消耗: 18.5 MB, 提交时间: 2023-09-19 16:50:48
class Solution: def trapRainWater(self, heightMap: List[List[int]]) -> int: if len(heightMap) <= 2 or len(heightMap[0]) <= 2: return 0 m, n = len(heightMap), len(heightMap[0]) visited = [[0 for _ in range(n)] for _ in range(m)] pq = [] for i in range(m): for j in range(n): if i == 0 or i == m - 1 or j == 0 or j == n - 1: visited[i][j] = 1 heapq.heappush(pq, (heightMap[i][j], i * n + j)) res = 0 dirs = [-1, 0, 1, 0, -1] while pq: height, position = heapq.heappop(pq) for k in range(4): nx, ny = position // n + dirs[k], position % n + dirs[k + 1] if nx >= 0 and nx < m and ny >= 0 and ny < n and visited[nx][ny] == 0: if height > heightMap[nx][ny]: res += height - heightMap[nx][ny] visited[nx][ny] = 1 heapq.heappush(pq, (max(height, heightMap[nx][ny]), nx * n + ny)) return res
java 解法, 执行用时: 26 ms, 内存消耗: 43 MB, 提交时间: 2023-09-19 16:50:35
class Solution { public int trapRainWater(int[][] heightMap) { if (heightMap.length <= 2 || heightMap[0].length <= 2) { return 0; } int m = heightMap.length; int n = heightMap[0].length; boolean[][] visit = new boolean[m][n]; PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]); 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) { pq.offer(new int[]{i * n + j, heightMap[i][j]}); visit[i][j] = true; } } } int res = 0; int[] dirs = {-1, 0, 1, 0, -1}; while (!pq.isEmpty()) { int[] curr = pq.poll(); for (int k = 0; k < 4; ++k) { int nx = curr[0] / n + dirs[k]; int ny = curr[0] % n + dirs[k + 1]; if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visit[nx][ny]) { if (curr[1] > heightMap[nx][ny]) { res += curr[1] - heightMap[nx][ny]; } pq.offer(new int[]{nx * n + ny, Math.max(heightMap[nx][ny], curr[1])}); visit[nx][ny] = true; } } } return res; } }
cpp 解法, 执行用时: 64 ms, 内存消耗: 12.8 MB, 提交时间: 2023-09-19 16:50:21
// 最小堆 typedef pair<int,int> pii; class Solution { public: int trapRainWater(vector<vector<int>>& heightMap) { if (heightMap.size() <= 2 || heightMap[0].size() <= 2) { return 0; } int m = heightMap.size(); int n = heightMap[0].size(); priority_queue<pii, vector<pii>, greater<pii>> pq; vector<vector<bool>> visit(m, vector<bool>(n, false)); 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) { pq.push({heightMap[i][j], i * n + j}); visit[i][j] = true; } } } int res = 0; int dirs[] = {-1, 0, 1, 0, -1}; while (!pq.empty()) { pii curr = pq.top(); pq.pop(); for (int k = 0; k < 4; ++k) { int nx = curr.second / n + dirs[k]; int ny = curr.second % n + dirs[k + 1]; if( nx >= 0 && nx < m && ny >= 0 && ny < n && !visit[nx][ny]) { if (heightMap[nx][ny] < curr.first) { res += curr.first - heightMap[nx][ny]; } visit[nx][ny] = true; pq.push({max(heightMap[nx][ny], curr.first), nx * n + ny}); } } } return res; } };