Java/Heap,  clean code, 30 line, comments
\nclass Solution {\n    int[][] directions = new int[][] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n    \n    public int trapRainWater(int[][] heightMap) {\n        i
```\nclass Solution {\n    int[][] directions = new int[][] {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n    \n    public int trapRainWater(int[][] heightMap) {\n        int xSize = heightMap.length;\n        int ySize = heightMap[0].length;\n        \n        // Use heap to traverse matrix from outer layer to the inner layer\n        // Heap helps us to always get smallest element and propagate its value to the inner layers\n        // Queue contains 0,1 - x,y and height - is maximum water height that cell at x,y could hold\n        PriorityQueue<int[]> cells = new PriorityQueue<>((c1, c2) -> Integer.compare(c1[2], c2[2]));\n        boolean[][] visited = new boolean[xSize][ySize];\n        \n        // add all boundary nodes, since they couldn\'t hold any water\n        for(int i=0;i<xSize;i++) {\n            for(int j=0;j<ySize;j++) {\n                if (i == 0 || j == 0 || i == xSize-1 || j == ySize-1) {\n                    cells.add(new int[]{i, j, heightMap[i][j]});\n                    visited[i][j]=true;        \n                }\n            }\n        }\n        \n        int result = 0;\n        while(!cells.isEmpty()) {\n            int[] cell = cells.poll();\n            // add water height\n            result += cell[2]-heightMap[cell[0]][cell[1]];\n\t\t\t\n\t\t\t// check non visited neighbor cells of current cell\n            for(int[] direction : directions) {\n                int ni = cell[0]+direction[0];\n                int nj = cell[1]+direction[1];\n                \n                if (ni>=0 && nj>=0 && ni<xSize && nj<ySize && !visited[ni][nj]) {\n                    // water level is propagated from current cell if it\'s higher than current cells height\n\t\t\t\t\t// travesring from min to max guarantee that we always visit neighbors from min value cell\n                    int maxWaterLevel = Math.max(heightMap[ni][nj], cell[2]);\n                    cells.add(new int[]{ni,nj, maxWaterLevel});\n                    visited[ni][nj] = true;\n                }\n            }    \n        }\n        \n        return result;\n    }\n}\n```
[]