问题描述:
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!
基本思路:
本题通过分析可以发现,存储水的槽的两边都是槽高的极大值。(这里对于最左边的曹,只要大于等于它右面的即可。最右边的同理)
但是单纯的考量 每两个极大值的槽作为水槽的两边得到的结果是不对的。举个例子:
A = {9,2, 9, 2,2,1,8}
这里如果只考虑每两个极大值之间存放的水,结果是7+0+1 = 8. 而实际上最大的结果应该是7+6+6+7 = 26.
所以,以没有计算过的最左的槽为左槽,找到符合以下条件之一的槽为右槽:
- 该槽的槽高>= 最左的槽高
- 该槽是最左槽右侧槽中槽高最大的。
(PS:此题我写了好久。。。 总是有地方出错。 后来发现是局部极大值和局部极大值的位置搞错了-.-|| )
代码:
int trap(int A[], int n) { //C++
if(n < 3)
return 0;
vector<int> locmaxs;
int sum = 0;
int i = 0;
while(i < n)
{
if(i == 0 && A[0] >= A[1])
{
locmaxs.push_back(0);
i++;
}
else if(i == n-1 && A[n-1] >= A[n-2])
{
locmaxs.push_back(n-1);
i++;
}
else if(A[i] >= A[i-1] && A[i] >= A[i+1])
{
locmaxs.push_back(i);
i++;
}
else i++;
}
for(i = 0; i < locmaxs.size()-1; )
{
int pos = i+1 ,max = locmaxs[i+1];
for( int j = i+1; j < locmaxs.size(); j++)
{
if(A[locmaxs[j]] >= A[locmaxs[i]])
{
pos = j;
break;
}
if(A[locmaxs[j]] > A[max])
{
max = locmaxs[j];
pos = j;
}
}
int draw = ((A[locmaxs[i]] > A[locmaxs[pos]]) ? A[locmaxs[pos]]: A[locmaxs[i]]);
for(int j = locmaxs[i]+1; j < locmaxs[pos]; j++)
if(draw - A[j] >0)
sum += draw - A[j];
i = pos;
}
return sum;
}