# 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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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