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
.
如果直接从左向右计算,那么存在的情况十分多
如果换个思路,从两边向中间,那么题目就简单很多了保存一个次高位的数据,如果有不理解,自己画个图,就很好理解了。
class Solution {
public:
int trap(int A[], int n) {
if(A == NULL || n == 0)
{
return 0;
}
int nextMax = 0;
int left = 0;
int right = n-1;
int res = 0;
while(left < right)
{
if(A[left] < A[right])
{
nextMax = max(A[left],nextMax);
res += nextMax-A[left++];
}
else
{
nextMax = max(A[right],nextMax);
res += nextMax-A[right--];
}
}
return res;
}
};
主要的思路就是如果一个阶段,最左边和最右边将中间的值包围起来,那么就可以利用这种方式计算
但是如果不是这种情况,比如 9 6 8 8 5 6 3 6
这种情况就很困难,之后回来将这种方法补全,不推荐
#include<iostream>
#include<vector>
using namespace std;
int CalRain(vector<int> &temp)
{
int len = temp.size();
if(len == 0 || len == 1)
{
return 0;
}
int res = 0;
int max = temp[0];
int nextmax = 0;
int maxIndext = 0;
int nextIndxt = 1;
bool flag = 0;
for(int i = 2; i < len; i++)
{
if(temp[i] >temp[i-1])
{
flag = 1;//<说明有储水
nextmax = temp[i];
nextIndxt = i;
}
if(flag)
{
if(temp[i] > nextmax)
{
nextmax = temp[i];
nextIndxt = i;
}
}
}
if(!flag) return 0;
nextmax = (nextmax > max)?max:nextmax;
for(int i = 1; i < nextIndxt; i++)
{
if((nextmax-temp[i]) > 0)
res += (nextmax-temp[i]);
}
return res;
}
int trap(int A[], int n) {
if(A == NULL || n == 0)
{
return 0;
}
vector<int> temp;
int max = A[0];
int res = 0;
temp.push_back(A[0]);
for(int i = 1; i < (n-1); i++)
{
temp.push_back(A[i]);
if(A[i] >= max && A[i+1] < A[i])//<可以以此条件判断
{
res += CalRain(temp);
temp.clear();
temp.push_back(A[i]);//<下一个模块还可以用
max = A[i];
}
if(A[i] > max)
{
max = A[i];
}
}
if(!temp.empty())
{
temp.push_back(A[n-1]);
res += CalRain(temp);
}
return res;
}
int main()
{
int A[7] = {9,6,8,8,5,6,3};
int res = trap(A,7);
int i = res;
return 0;
}