【算法】C++经典算法题——接雨水!

一、题目介绍

接雨水是面试时经常考察的算法题,见LeetCode 42. 接雨水,题目描述如下:

该题可以用暴力解法求解,或者用双指针法优化暴力解法。这里只介绍单调栈解法。

二、单调栈解法

单调栈就是保持栈内元素有序。和【算法】代码随想录刷题记录 | 5. 栈与队列篇中的LeetCode 347. 前K个高频元素使用的优先队列一样,需要我们自己维持顺序,没有现成的容器可以用。

通常是一维数组要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。

而接雨水这道题目,我们正需要寻找一个元素,右边最大元素以及左边最大元素,来计算雨水面积。

那么本题使用单

假设我们要解决一个经典的计算机科学问——“雨水”(也称为“小船雨水”或“求最大面积”),这是一个二维数组的问,通常涉及到动态规划或模拟的方法。这里以城市地图的“城西”区域为例,描述如何编写一个程序来计算在给定的降雨量分布下,可以收集到的雨水的最大容量。 首先,定义一个函数`maxWater(int[][] cityMap)`,其中`cityMap`代表每个网格点的高度,表示该地点的雨量。我们可以将其转换为C++代码如下: ```cpp #include <vector> #include <algorithm> int maxWater(std::vector<std::vector<int>>& cityMap) { // 确保输入合法 if (cityMap.empty() || cityMap[0].empty()) { return 0; } int m = cityMap.size(); int n = cityMap[0].size(); // 初始化两个变量,分别记录左边界和右边界的最大水深 std::vector<int> leftMax(n, 0); std::vector<int> rightMax(n, 0); // 遍历矩阵,更新左右边界的最大水深 for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { leftMax[j] = std::max(leftMax[j], cityMap[i][j]); rightMax[n - j], cityMap[i][j]); } } // 使用双指针法找到最大的连续平坦区 int totalWater = 0; for (int i = 0; i < m; ++i) { int minHeight = std::numeric_limits<int>::max(); // 初始化为无穷大 for (int j = 0; j < n; ++j) { minHeight = std::min(minHeight, cityMap[i][j]); if (minHeight > 0) { totalWater += std::min(leftMax[j], rightMax[j]) - minHeight; } } } return totalWater; } ``` 这个函数通过遍历地图并维护每行的左右两侧最高水位,然后计算出每次下雨后,可以收到的最大水量,最后累计所有能收到的雨水。注意,这个算法适用于非负的降雨量数组。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值