Trapping Rain Water II

hard heap bfs matrix

Problem

Given an m×n elevation map, compute the volume of water it can trap after raining.

InputheightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]
Output4
A min-heap of border cells lets the algorithm flood inward in non-decreasing barrier order.

import heapq
def trap_rain_water(h):
    m, n = len(h), len(h[0])
    if m < 3 or n < 3: return 0
    heap = []
    seen = [[False]*n for _ in range(m)]
    for r in range(m):
        for c in range(n):
            if r in (0, m-1) or c in (0, n-1):
                heapq.heappush(heap, (h[r][c], r, c))
                seen[r][c] = True
    water = 0
    while heap:
        ht, r, c = heapq.heappop(heap)
        for dr, dc in [(-1,0),(1,0),(0,-1),(0,1)]:
            nr, nc = r + dr, c + dc
            if 0 <= nr < m and 0 <= nc < n and not seen[nr][nc]:
                seen[nr][nc] = True
                water += max(0, ht - h[nr][nc])
                heapq.heappush(heap, (max(ht, h[nr][nc]), nr, nc))
    return water
function trapRainWater(h) {
  const m = h.length, n = h[0].length;
  if (m < 3 || n < 3) return 0;
  const heap = [];
  const seen = Array.from({length: m}, () => new Array(n).fill(false));
  function push(p) { heap.push(p); heap.sort((a, b) => a[0] - b[0]); }
  function pop() { return heap.shift(); }
  for (let r = 0; r < m; r++) for (let c = 0; c < n; c++)
    if (r === 0 || r === m - 1 || c === 0 || c === n - 1) { push([h[r][c], r, c]); seen[r][c] = true; }
  let water = 0;
  while (heap.length) {
    const [ht, r, c] = pop();
    for (const [dr, dc] of [[-1,0],[1,0],[0,-1],[0,1]]) {
      const nr = r + dr, nc = c + dc;
      if (nr < 0 || nr >= m || nc < 0 || nc >= n || seen[nr][nc]) continue;
      seen[nr][nc] = true;
      water += Math.max(0, ht - h[nr][nc]);
      push([Math.max(ht, h[nr][nc]), nr, nc]);
    }
  }
  return water;
}
class Solution {
    public int trapRainWater(int[][] h) {
        int m = h.length, n = h[0].length;
        if (m < 3 || n < 3) return 0;
        PriorityQueue heap = new PriorityQueue<>((a, b) -> a[0] - b[0]);
        boolean[][] seen = new boolean[m][n];
        for (int r = 0; r < m; r++) for (int c = 0; c < n; c++)
            if (r == 0 || r == m - 1 || c == 0 || c == n - 1) { heap.add(new int[]{ h[r][c], r, c }); seen[r][c] = true; }
        int[][] D = {{-1,0},{1,0},{0,-1},{0,1}};
        int water = 0;
        while (!heap.isEmpty()) {
            int[] cur = heap.poll();
            for (int[] d : D) {
                int nr = cur[1] + d[0], nc = cur[2] + d[1];
                if (nr < 0 || nr >= m || nc < 0 || nc >= n || seen[nr][nc]) continue;
                seen[nr][nc] = true;
                water += Math.max(0, cur[0] - h[nr][nc]);
                heap.add(new int[]{ Math.max(cur[0], h[nr][nc]), nr, nc });
            }
        }
        return water;
    }
}
int trapRainWater(vector>& h) {
    int m = h.size(), n = h[0].size();
    if (m < 3 || n < 3) return 0;
    priority_queue, vector>, greater<>> heap;
    vector> seen(m, vector(n, false));
    for (int r = 0; r < m; r++) for (int c = 0; c < n; c++)
        if (r == 0 || r == m - 1 || c == 0 || c == n - 1) { heap.push({h[r][c], r, c}); seen[r][c] = true; }
    int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};
    int water = 0;
    while (!heap.empty()) {
        auto [ht, r, c] = heap.top(); heap.pop();
        for (int k = 0; k < 4; k++) {
            int nr = r + dr[k], nc = c + dc[k];
            if (nr < 0 || nr >= m || nc < 0 || nc >= n || seen[nr][nc]) continue;
            seen[nr][nc] = true;
            water += max(0, ht - h[nr][nc]);
            heap.push({max(ht, h[nr][nc]), nr, nc});
        }
    }
    return water;
}
Time: O(mn log(mn)) Space: O(mn)