koenjazh-CNfresde
짬뽕얼큰하게의 맨땅에 헤딩 :: Trapping Rain Water II

Leetcode Problem:

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

  • O(m*n*log(m*n))

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) {
        // Direction arrays
        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 (min-heap) to process boundary cells in increasing
        // height order
        priority_queue boundary;

        // Add the first and last column cells to the boundary and mark them as
        // visited
        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));
            // Mark left and right boundary cells as visited
            visited[i][0] = visited[i][numOfCols - 1] = true;
        }

        // Add the first and last row cells to the boundary and mark them as
        // visited
        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));
            // Mark top and bottom boundary cells as visited
            visited[0][i] = visited[numOfRows - 1][i] = true;
        }

        int totalWaterVolume = 0;

        while (!boundary.empty()) {
            // Pop the cell with the smallest height from the boundary
            Cell currentCell = boundary.top();
            boundary.pop();

            int currentRow = currentCell.row;
            int currentCol = currentCell.col;
            int minBoundaryHeight = currentCell.height;

            // Explore all 4 neighboring cells
            for (int direction = 0; direction < 4; direction++) {
                int neighborRow = currentRow + dRow[direction];
                int neighborCol = currentCol + dCol[direction];

                // Check if the neighbor is within the grid bounds and not yet
                // visited
                if (isValidCell(neighborRow, neighborCol, numOfRows,
                                numOfCols) &&
                    !visited[neighborRow][neighborCol]) {
                    int neighborHeight = heightMap[neighborRow][neighborCol];

                    // If the neighbor's height is less than the current
                    // boundary height, water can be trapped
                    if (neighborHeight < minBoundaryHeight) {
                        totalWaterVolume += minBoundaryHeight - neighborHeight;
                    }

                    // Push the neighbor into the boundary with updated height
                    // (to prevent water leakage)
                    boundary.push(Cell(max(neighborHeight, minBoundaryHeight),
                                       neighborRow, neighborCol));
                    visited[neighborRow][neighborCol] = true;
                }
            }
        }

        return totalWaterVolume;
    }

private:
    // Struct to store the height and coordinates of a cell in the grid
    class Cell {
    public:
        int height;
        int row;
        int col;

        // Constructor to initialize a cell
        Cell(int height, int row, int col)
            : height(height), row(row), col(col) {}

        // Overload the comparison operator to make the priority queue a
        // min-heap based on height
        bool operator<(const Cell& other) const {
            // Reverse comparison to simulate a min-heap
            return height >= other.height;
        }
    };

    // Helper function to check if a cell is valid (within grid bounds)
    bool isValidCell(int row, int col, int numOfRows, int numOfCols) {
        return row >= 0 && col >= 0 && row < numOfRows && col < numOfCols;
    }
};

'알고리즘' 카테고리의 다른 글

Grid Game  (0) 2025.03.05
First Completely Painted Row or Column  (0) 2025.03.05
Minimum Cost to Make at Least One Valid Path in a Grid  (0) 2025.03.05
Neighboring Bitwise XOR  (0) 2025.03.05
Check if Number is a Sum of Powers of Three  (0) 2025.03.04
블로그 이미지

짬뽕얼큰하게

,