Python with heapq and explanation, time O(nlogn)
\nVisit boundary first\nappend( height[x][y] (x, y) ) to a list\nheapify the list and start from the point with smallest height to check its neighbor.\nIf neigh
\nVisit boundary first\nappend( height[x][y] (x, y) ) to a list\nheapify the list and start from the point with smallest height to check its neighbor.\nIf neighbor has height higher than start point water_top, then this neighbor cannot hold water with water_top as its height\nOtherwise the neighbor holds the same amount of water with the same water_top as start point.\nAdd the water the neighbor can hold to results.\nAppend the visited neighbor to heap.\nReturn final results when heap is empty\nTime: O(nlogn), n is the total size of heightMap\nSpace: O(n)\n\n```\nimport heapq\n\nclass Solution:\n    def trapRainWater(self, heightMap: List[List[int]]) -> int:\n        if not heightMap or not heightMap[0] or len(heightMap)<3 or len(heightMap[0])<3:\n            return 0\n        \n        row_limit, col_limit = len(heightMap), len(heightMap[0])\n        height_dict = {}\n        water_top_heap = []\n        # Check bondary first\n        for c in range(col_limit):\n            # Top boundary\n            water_top_heap.append( (heightMap[0][c], (0, c)) )\n            height_dict[(0, c)] = (heightMap[0][c])\n            # Bottom boundary\n            water_top_heap.append( (heightMap[row_limit-1][c], (row_limit-1, c)) )\n            height_dict[(row_limit-1, c)] = (heightMap[row_limit-1][c])\n        for r in range(row_limit):\n            if (r, 0) not in height_dict:\n                # Left boundary\n                water_top_heap.append( (heightMap[r][0], (r, 0)) )\n                height_dict[(r, 0)] = (heightMap[r][0])\n            if (r, col_limit-1) not in height_dict:\n                # Right boundary\n                water_top_heap.append( (heightMap[r][col_limit-1], (r, col_limit-1)) )\n                height_dict[(r, col_limit-1)] = (heightMap[r][col_limit-1])\n        heapq.heapify(water_top_heap)\n    \n        res = 0\n        dr, dc = [0, 1, 0, -1], [1, 0, -1, 0]\n        while water_top_heap:\n            cur_height, cur_pos = heapq.heappop(water_top_heap)\n            for i in range(4):\n                nr, nc = cur_pos[0] + dr[i], cur_pos[1] + dc[i]\n                if 0<=nr<row_limit and 0<=nc<col_limit and (nr, nc) not in height_dict:\n                    if heightMap[nr][nc] > height_dict[cur_pos]: \n                        height_dict[(nr, nc)] = heightMap[nr][nc]\n                    else:\n                        height_dict[(nr, nc)] = height_dict[cur_pos]\n                    res += height_dict[(nr, nc)] - heightMap[nr][nc]\n                    heapq.heappush(water_top_heap, (heightMap[nr][nc], (nr, nc)) )\n        return res\n```
[]