您的位置:首页 > 移动开发

Trapping Rain Water

2016-04-18 21:23 344 查看
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
.

自己第一个思路:(最蠢的,勿参考,提交后当数量比较大时会超时)

1.先对头和尾进行判断,两个指针移动,知道前后都不是0.(开头和结尾都是0是不能存储水的)

如:对以上数列,begin=1,end=len-1.

2.循环中:while(begin < end)

1)对这个数列进行遍历一遍,找到为0的个数就是蓄水的数量。遍历结束后,将这个值加到总和上去;

2)然后再遍历这个数列,找到最小的那一个的长度min(如果min为0,就将min设为1);

3)再遍历一遍,将每个数减去min,得到每个数的新的长度。若得到的长度为负数,置为0;

4)再对begin和end进行处理,找到前后都不是0的位置,重置begin和end的值;

3.循环结束后,得到的总和就是需要的结果。

4.附上代码:(虽然很挫,但不能作为思路参考)

int trap(vector<int>& height) {
int len = height.size();
if(len < 3)
return 0;
int j = 0;
while(height[j]==0 && j < len) //找到第一个不是0的位置
j++;
if(j == len && j >=0) //都是0
return 0;
int beg = j;
j = len-1;
while(height[j]==0)
j--;
int end = j;//忽略后面都是0的位置
int sum = 0;
while(beg < end){
int sum_part = 0;
for(int k = beg; k <= end; k++){
if(height[k] == 0)
sum_part ++;
}
sum+=sum_part;
int min = INT_MAX;
for(int k = beg; k <= end; k++){
if(height[k]<min)
min = height[k];
}
if(min <= 0) min = 1;
for(int k = beg; k <= end; k++){
if(height[k]-min < 0)
height[k] = 0;
else
height[k] = height[k]-min;
}
j = 0;
while(height[j]==0 && j < len) //找到第一个不是0的位置
j++;
beg = j;
j = len-1;
while(height[j]==0 && j >= 0)
j--;
end = j;
}
return sum;
}

2.自己的思路二:

用栈。

1. 遍历每个数,若小于下一个数,就将其压入栈中;

2. 否则,判断将栈中小于当前数的那些数取出来;直到取到stack.top() >current为止

3. 若取到栈为空了,则判断栈中最后个元素和当前元素谁更大,则进行计算

4.若栈为空,则把当前元素加入栈中;否则,将之前的那些个数仍加入栈中

int trap(vector<int>& height) {
int len = height.size();
if(len < 3)
return 0 ;
int j = 0;
while(height[j] == 0 && j < len)
j++;
if(j == len)
return 0;
int beg = j;
j = len - 1;
while(height[j] == 0 && j >= 0)
j--;
int end = j;
stack<int> stk;
stk.push(height[beg]);
int former = height[beg];
beg++;
int sum = 0;
while(beg<=end){
if(height[beg] <= stk.top()){
stk.push(height[beg]);
beg++;
}else{
int num = 0;
int sum_part = 0, sum_all = 0;
while(!stk.empty()&& height[beg] > stk.top()){
sum_all += stk.top();
num++;
stk.pop();
}
if(!stk.empty()){
sum_part = height[beg]*num - sum_all;
for(int k = 0; k <= num; k++){
stk.push(height[beg]);
}
}else{
sum_part = former*num - sum_all;
former = height[beg];
stk.push(height[beg]);
}
sum += sum_part;
beg++;
}
}
return sum;
}


3.别人的好的思路和代码

class Solution {
public:
int trap(int A[], int n) {
int left=0; int right=n-1;
int res=0;
int maxleft=0, maxright=0;
while(left<=right){
if(A[left]<=A[right]){
if(A[left]>=maxleft) maxleft=A[left];
else res+=maxleft-A[left];
left++;
}
else{
if(A[right]>=maxright) maxright= A[right];
else res+=maxright-A[right];
right--;
}
}
return res;
}
};


4.同上

1) With left and right index.

int trap(vector<int>& height) {
int l = 0, r = height.size()-1, level = 0, water = 0;
while (l < r) {
int lower = height[height[l] < height[r] ? l++ : r--];
level = max(level, lower);
water += level - lower;
}
return water;
}

2)With left and right iterator.

int trap(vector<int>& height) {
auto l = height.begin(), r = height.end() - 1;
int level = 0, water = 0;
while (l != r + 1) {
int lower = *l < *r ? *l++ : *r--;
level = max(level, lower);
water += level - lower;
}
return water;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  two point leetcode c++ array