Summary
- This solution calculates the volume of water that can be trapped in a given 2D elevation map after raining.
Approach
- The approach used in this solution is to simulate the process of rainwater trapping using a priority queue to process boundary cells in increasing height order
- It uses a breadth-first search (BFS) approach to explore neighboring cells and calculate the trapped water volume.
Complexity
Explanation
- The solution starts by initializing a priority queue with boundary cells and marking them as visited
- Then, it enters a loop where it pops the cell with the smallest height from the boundary, explores its neighboring cells, and calculates the trapped water volume
- The solution uses a helper function to check if a cell is valid and another helper function to compare cells based on height
- The time complexity is O(m*n*log(m*n)) due to the priority queue operations and the BFS exploration.
Solution Code:
class Solution {
public:
int trapRainWater(vector>& heightMap) {
int dRow[4] = {0, 0, -1, 1};
int dCol[4] = {-1, 1, 0, 0};
int numOfRows = heightMap.size();
int numOfCols = heightMap[0].size();
vector> visited(numOfRows, vector(numOfCols, false));
priority_queue boundary;
for (int i = 0; i < numOfRows; i++) {
boundary.push(Cell(heightMap[i][0], i, 0));
boundary.push(Cell(heightMap[i][numOfCols - 1], i, numOfCols - 1));
visited[i][0] = visited[i][numOfCols - 1] = true;
}
for (int i = 0; i < numOfCols; i++) {
boundary.push(Cell(heightMap[0][i], 0, i));
boundary.push(Cell(heightMap[numOfRows - 1][i], numOfRows - 1, i));
visited[0][i] = visited[numOfRows - 1][i] = true;
}
int totalWaterVolume = 0;
while (!boundary.empty()) {
Cell currentCell = boundary.top();
boundary.pop();
int currentRow = currentCell.row;
int currentCol = currentCell.col;
int minBoundaryHeight = currentCell.height;
for (int direction = 0; direction < 4; direction++) {
int neighborRow = currentRow + dRow[direction];
int neighborCol = currentCol + dCol[direction];
if (isValidCell(neighborRow, neighborCol, numOfRows,
numOfCols) &&
!visited[neighborRow][neighborCol]) {
int neighborHeight = heightMap[neighborRow][neighborCol];
if (neighborHeight < minBoundaryHeight) {
totalWaterVolume += minBoundaryHeight - neighborHeight;
}
boundary.push(Cell(max(neighborHeight, minBoundaryHeight),
neighborRow, neighborCol));
visited[neighborRow][neighborCol] = true;
}
}
}
return totalWaterVolume;
}
private:
class Cell {
public:
int height;
int row;
int col;
Cell(int height, int row, int col)
: height(height), row(row), col(col) {}
bool operator<(const Cell& other) const {
return height >= other.height;
}
};
bool isValidCell(int row, int col, int numOfRows, int numOfCols) {
return row >= 0 && col >= 0 && row < numOfRows && col < numOfCols;
}
};