java version
```\npublic class Solution {\n    public int trapRainWater(int[][] heightMap) {\n        class Cell{\n            int x;\n            int y;\n            int h;
```\npublic class Solution {\n    public int trapRainWater(int[][] heightMap) {\n        class Cell{\n            int x;\n            int y;\n            int h;\n            Cell(int x, int y, int height){\n                this.x = x;\n                this.y = y;\n                h = height;\n            }\n        }\n         if (heightMap == null || heightMap.length == 0 || heightMap[0].length == 0) {\n            return 0;\n        }\n\n        int m = heightMap.length;\n        int n = heightMap[0].length;\n        PriorityQueue<Cell> pq = new PriorityQueue<>((v1,v2)->v1.h - v2.h);\n         boolean[][] visited = new boolean[m][n];\n        for(int i = 0; i < n; i++){\n            visited[0][i] = true;\n            visited[m-1][i] = true;\n            pq.offer( new Cell(0, i, heightMap[0][i]));\n            pq.offer(new Cell(m-1, i, heightMap[m-1][i]));\n        }\n        for(int i = 1; i < m-1; i++){\n            visited[i][0] = true;\n            visited[i][n-1] = true;\n            pq.offer(new Cell(i, 0, heightMap[i][0]));\n            pq.offer(new Cell(i, n-1, heightMap[i][n-1]));\n        }\n        int[] xs = {0,  0, 1, -1};\n        int[] ys = {1, -1, 0,  0};\n        int sum = 0;\n        while (!pq.isEmpty()) {\n            Cell cell = pq.poll();\n            for (int i = 0; i < 4; i++) {\n                int nx = cell.x + xs[i];\n                int ny = cell.y + ys[i];\n                if (nx >= 0 && nx < m && ny >= 0 && ny < n && !visited[nx][ny]) {\n                    visited[nx][ny] = true;\n                    sum += Math.max(0, cell.h - heightMap[nx][ny]);\n                    pq.offer(new Cell(nx, ny, Math.max(heightMap[nx][ny], cell.h)));\n                }\n            }\n        }\n        return sum;\n    }\n}
[]