📜  在矩阵中捕获雨水

📅  最后修改于: 2021-10-28 02:07:54             🧑  作者: Mango

给定一个由正整数组成的维度为M*N的矩阵 arr[][] ,其中 arr[i][j]表示每个单元格的高度,任务是找到雨后矩阵中困住的水的总体积.

例子:

方法:给定的问题可以通过使用贪心技术和最小堆来解决。请按照以下步骤解决问题:

  • 使用priority_queue初始化最小堆,比如PQ ,以存储单元格的位置及其高度。
  • 推送 PQ中的所有边界单元并将所有推送的单元标记为已访问。
  • 初始化两个变量,假设ans0maxHeight0分别存储 PQ中所有单元格的总体积和最大高度。
  • 迭代直到PQ不为空并执行以下步骤:
    • 将 PQ的顶部节点存储在一个变量中,比如front并擦除 PQ的顶部元素。
    • 将 maxHeight的值更新为 maxHeightfront.height的最大值。
    • 现在,遍历当前单元格的所有相邻节点(front.X,front.Y)并执行以下操作:
      • 如果相邻单元格有效,即该单元格未越界且尚未访问,则将相邻单元格的值推入PQ。
      • 如果相邻单元格的高度小于maxHeight则将ans增加 maxHeight与相邻单元格高度的差值。
  • 最后,完成上述步骤后,将an的值打印为雨后截留的水。

下面是上述方法的实现:

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[0].size();
  
    // Stores if a cell of the matrix
    // is visited or not
    vector > visited(M,
                                  vector(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 boundry
            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][0];
            int new_y = curr_y + dir[i][1];
  
            // 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;
}


输出
4

时间复杂度: (N * M * log(N * M))
辅助空间: O(N * M)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。