给定一个由正整数组成的维度为M*N的矩阵 arr[][] ,其中 arr[i][j]表示每个单元格的高度,任务是找到雨后矩阵中困住的水的总体积.
例子:
Input: arr[][] = {{4, 2, 7}, {2, 1, 10}, {5, 10, 2}}
Output: 1
Explanation:
The rain water can be trapped in the following way:
- 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.
- 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
方法:给定的问题可以通过使用贪心技术和最小堆来解决。请按照以下步骤解决问题:
- 使用priority_queue初始化最小堆,比如PQ ,以存储单元格的位置对及其高度。
- 推送 PQ中的所有边界单元并将所有推送的单元标记为已访问。
- 初始化两个变量,假设ans为0和maxHeight为0分别存储 PQ中所有单元格的总体积和最大高度。
- 迭代直到PQ不为空并执行以下步骤:
- 将 PQ的顶部节点存储在一个变量中,比如front ,并擦除 PQ的顶部元素。
- 将 maxHeight的值更新为 maxHeight和front.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 现场工作专业课程和学生竞争性编程现场课程。