code第一部分:数组 第十四题 雨水问题
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
对于每个柱子,找到其左右两边最高的柱子,该柱子能容纳的面积就是 min(max_left,
max_right) - height。所以,
1. 从左往右扫描一遍,对于每个柱子,求取左边最大值;
2. 从右往左扫描一遍,对于每个柱子,求最大右值;
3. 再扫描一遍,把每个柱子的面积并累加。
第一种方案的时间复杂度O(N),空间复杂度为O(N);
解决方案2
1. 扫描一遍,找到最高的柱子,这个柱子将数组分为两半;
2. 处理左边一半;
3. 处理右边一半。
第二种方案的时间复杂度O(N),空间复杂度为O(1);
解决方案3
使用栈;用一个栈辅助,小于栈顶的元素压入,大于等于栈顶就把栈里所有小于或等于当
前值的元素全部出栈处理掉。
时间复杂度 O(n),空间复杂度 O(n)
#include <iostream> #include <stack> using namespace std; int min(int n,int m) { if (n>m) { return m; } else return n; } int water(int a[],int n) { int i; const int count=n; int b[count]; int c[count]; int sum1=0; for (i = 1; i < count; i++) { if (a[i]>sum1) { sum1=a[i]; } b[i]=sum1; } int j; int sum2=0; for (j = count-2; j >=0; j--) { if (a[j]>sum2) { sum2=a[j]; } c[j]=sum2; } int sum=0; int k; for (k = 1; k < count-1; k++) { sum+=min(b[k],c[k])-a[k]; } return sum; } int water2(int a[],int n) { int i=0; int max=0; int pos=0; for (i = 0; i < n; i++) { if(a[i]>max) { max=a[i]; pos=i; } } int j; int sum1=a[0]; int ans=0; for (j = 1; j < pos; j++) { if (a[j]>=sum1) { sum1=a[j]; } else { ans+=sum1-a[j]; } } int sum2=a[n-1]; int k; for (k = n-2; k>pos; k--) { if (a[k]>sum2) { sum2=a[k]; } else { ans+=sum2-a[k]; } } return ans; } int water3(int a[], int n) { stack<pair<int, int>> s; int water = 0; for (int i = 0; i < n; ++i) { int height = 0; while (!s.empty()) { // 将栈里比当前元素矮或等高的元素全部处理掉 int bar = s.top().first; int pos = s.top().second; // bar, height, a[i] 三者夹成的凹陷 water += (min(bar, a[i]) - height) * (i - pos - 1); height = bar; if (a[i] < bar) // 碰到了比当前元素高的,跳出循环 break; else s.pop(); // 弹出栈顶,因为该元素处理完了,不再需要了 } s.push(make_pair(a[i], i)); } return water; } int main() { int a[12]={0,1,0,2,1,0,1,3,2,1,2,1}; int ans1=water(a,12); cout<<"ans1 is "<<ans1<<endl; int ans2=water2(a,12); cout<<"ans2 is "<<ans2<<endl; int ans3=water3(a,12); cout<<"ans3 is "<<ans3<<endl; return 0; }