# Trapping Rain Water in a Matrix

• Difficulty Level : Hard
• Last Updated : 01 Sep, 2021

Given a matrix arr[][] of dimension M*N consisting of positive integers, where arr[i][j] represents the height of each unit cell, the task is to find the total volume of water trapped in the matrix after rain.

Examples:

Input: arr[][] = {{4, 2, 7}, {2, 1, 10}, {5, 10, 2}}
Output: 1
Explanation:
The rain water can be trapped in the following way:

1. The cells, {(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1), (2, 2)} traps 0 unit volume of rain water as all water goes out of the matrix as cells are on the boundary.
2. The cell (2, 2) traps 1 unit volume of rain water in between the cells {(0, 1), (1, 0), (1, 2), and (2, 1)}.

Therefore, a total of 1 unit volume of rain water has been trapped inside the matrix.

Input: arr[][] = {{1, 4, 3, 1, 3, 2}, {3, 2, 1, 3, 2, 4}, {2, 3, 3, 2, 3, 1}}
Output: 4

Approach: The given problem can be solved by using the Greedy Technique and Min-Heap. Follow the steps below to solve the problem:

• Initialize a Min-Heap using the priority_queue, say PQ, to store the pairs of positions of a cell and its height.
• Push all the boundary cells in the PQ and mark all the pushed cells as visited.
• Initialize two variables, say ans as 0 and maxHeight as 0 to store the total volume and the maximum height of all the cells in PQ respectively.
• Iterate until PQ is not empty and perform the following steps:
• Store the top node of PQ in a variable, say front, and erase the top element of PQ.
• Update the value of maxHeight as the maximum of maxHeight and front.height.
• Now, traverse to all the adjacent nodes of the current cell (front.X, front.Y) and do the following:
• If the adjacent cell is valid i.e, the cell is not out of bound and not yet visited, then, push the value of the adjacent cell into PQ.
• If the height of the adjacent cell is less than maxHeight then increment the ans by the difference of maxHeight and the height of the adjacent cell.
• Finally, after completing the above steps, print the value of ans as the resultant water trapped after rain.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ` `using` `namespace` `std;`   `// Stores the direction of all the` `// adjacent cells` `vector > dir` `    ``= { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } };`   `// Node structure` `struct` `node {`   `    ``int` `height;` `    ``int` `x, y;` `};`   `// Comparator function to implement` `// the min heap using priority queue` `struct` `Compare {`   `    ``// Comparator function` `    ``bool` `operator()(node ``const``& a, node ``const``& b)` `    ``{` `        ``return` `a.height > b.height;` `    ``}` `};`   `// Function to find the amount of water` `// the matrix is capable to hold` `int` `trapRainWater(vector >& heightMap)` `{` `    ``int` `M = heightMap.size();` `    ``int` `N = heightMap.size();`   `    ``// Stores if a cell of the matrix` `    ``// is visited or not` `    ``vector > visited(M,` `                                  ``vector<``bool``>(N, ``false``));`   `    ``// Initialize a priority queue` `    ``priority_queue, Compare> pq;`   `    ``// Traverse over the matrix` `    ``for` `(``int` `i = 0; i < M; i++) {` `        ``for` `(``int` `j = 0; j < N; j++) {`   `            ``// If element is not on` `            ``// the boundary` `            ``if` `(!(i == 0 || j == 0 || i == M - 1` `                  ``|| j == N - 1))` `                ``continue``;`   `            ``// Mark the current cell` `            ``// as visited` `            ``visited[i][j] = ``true``;`   `            ``// Node for priority queue` `            ``node t;` `            ``t.x = i;` `            ``t.y = j;` `            ``t.height = heightMap[i][j];`   `            ``// Pushe all the adjacent` `            ``// node in the pq` `            ``pq.push(t);` `        ``}` `    ``}`   `    ``// Stores the total volume` `    ``int` `ans = 0;`   `    ``// Stores the maximum height` `    ``int` `max_height = INT_MIN;`   `    ``// Iterate while pq is not empty` `    ``while` `(!pq.empty()) {`   `        ``// Store the top node of pq` `        ``node front = pq.top();`   `        ``// Delete the top element of pq` `        ``pq.pop();`   `        ``// Update the max_height` `        ``max_height = max(max_height, front.height);`   `        ``// Stores the position of the` `        ``// current cell` `        ``int` `curr_x = front.x;` `        ``int` `curr_y = front.y;`   `        ``for` `(``int` `i = 0; i < 4; i++) {`   `            ``int` `new_x = curr_x + dir[i];` `            ``int` `new_y = curr_y + dir[i];`   `            ``// If adjacent cells are out` `            ``// of bound or already visited` `            ``if` `(new_x < 0 || new_y < 0 || new_x >= M` `                ``|| new_y >= N || visited[new_x][new_y]) {` `                ``continue``;` `            ``}`   `            ``// Stores the height of the` `            ``// adjacent cell` `            ``int` `height = heightMap[new_x][new_y];`   `            ``// If height of current cell` `            ``// is smaller than max_height` `            ``if` `(height < max_height) {`   `                ``// Increment the ans by` `                ``// (max_height-height)` `                ``ans = ans + (max_height - height);` `            ``}`   `            ``// Define a new node` `            ``node temp;` `            ``temp.x = new_x;` `            ``temp.y = new_y;` `            ``temp.height = height;`   `            ``// Push the current node` `            ``// in the pq` `            ``pq.push(temp);`   `            ``// Mark the current cell` `            ``// as visited` `            ``visited[new_x][new_y] = ``true``;` `        ``}` `    ``}`   `    ``return` `ans;` `}`   `// Driver Code` `int` `main()` `{` `    ``vector > arr = { { 1, 4, 3, 1, 3, 2 },` `                                 ``{ 3, 2, 1, 3, 2, 4 },` `                                 ``{ 2, 3, 3, 2, 3, 1 } };` `    ``cout << trapRainWater(arr);`   `    ``return` `0;` `}`

Output

`4`

Time Complexity: (N * M * log(N * M))
Auxiliary Space: O(N * M)

My Personal Notes arrow_drop_up
Recommended Articles
Page :