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; } };
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; }