问题描述
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!
解题思路
这道题目看似比较复杂,但是仔细观察题目所给出的图片信息你就会发现一个规律,加入水后,图片的高度整体是从左右两边往中间的一个最高点单向增大的,所以这就给了我们一个很好的解题思路。先找到整张图的最高点,并记录它所在的位置,然后依次从左右两端往最该点遍历,遍历时记录左边遍历过的位置的最高点的值,当到达位置的实际高度小于我们记录的最高值,则表明此处有积水,由于宽度都是1,所以我们总积水的体积可以直接加上在此处实际高度与记录的最高高度的差值。当左右遍历完成后,所得结果及时总的积水体积。
代码展示
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
int trap(vector<int>& height) {
int size = height.size(); //得到容器的大小
if(size <= 2) return 0;
int max = -1, maxi = 0;
for(int i=0; i < size; ++i){
if(height[i] > max){
max = height[i]; //找到最高点,并记录最高点所在的位置
maxi = i;
}
}
int result = 0, nowheight=height[0]; //从左开始遍历
for(int j = 1; j < maxi;j++){
if(nowheight <height[j]) nowheight = height[j]; //记录遍历过的点的最大值
else result += (nowheight - height[j]); //最大值与现在值得差值即为此处积水
}
nowheight = height[size-1]; //从右开始遍历,方法与从左开始遍历一样
for(int k = size-1;k > maxi;k--){
if(nowheight < height[k]) nowheight = height[k];
else result += (nowheight - height[k]);
}
return result;
}
};
int main(){
int n;
vector<int> height;
cin>>n;
int num[n];
for(int i = 0;i<n;i++){
cin>>num[i];
height.push_back(num[i]);
}
Solution solution;
int result=solution.trap(height);
cout<<result<<endl;
}
运行结果展示