持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情
一、题目
描述:
给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个柱子高度图,计算按此排列的柱子,下雨之后能接多少雨水。(数组以外的区域高度视为0)
输入: [3, 1, 2, 5, 2 ,4]
输出: 5
#include <iostream>
#include <vector>
using namespace std;
long long maxWater(vector<int>& water) {
}
int main(int, char*[])
{
vector<int> water = {3, 1, 2, 5 ,2, 4};
cout << maxWater(water) << endl;
}
二、分析
由题意可知,要获得接雨水的大小,就是获取这个容器的大小。
一个完整的容器必须保证两条竖边形成U字形,若中间有更高的柱子,就分割形成两个容器。
通过不断的分割,最终会形成若干个完整的容器。
而容器的大小由两条竖边的最短边与中间柱子形成空格多少决定。
这种背景下,容器的体积由最短边决定,而是否形成新容器由最长边决定。
通过不断的寻求最高柱子,就能知道每个容器的边界。
每次迭代时,求最短边与临边的空格,就能知道当前容器的体积。
三、模拟
- 3,1,2,5,2,4 短边为3,暂无边界,当前容器最小边界为3
- 1,2,5,2,4 短边为1,与边界形成2个空格,当前容器最小边界为3
- 2,5,2,4 短边为2,与边界形成1个空格,当前容器最小边界为3
- 5,2,4 短边为4,暂无边界,当前容器最小边界为4
- 5,2 短边为2,与边界形成2个空格,当前容器最小边界为4
- 5 结束
四、实现
long long maxWater(vector<int>& water) {
if (water.empty())
return 0;
long long res = 0;
int left = 0;
int right = water.size() - 1;
int maxL = 0;
int maxR= 0;
while(left < right) {
maxL = max(maxL, water[left]);
maxR = max(maxR, water[right]);
if (maxR > maxL)
res += maxL - water[left++];
else
res += maxR - water[right--];
}
return res;
}
五、结言
这道题也是对动态规划的考量,通过对容器的划分,不断求容器的大小来达到最终的目的。
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!