code第一部分:數組 第十四題 雨水問題

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.ios

 

分析:
解決方案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;
}
相關文章
相關標籤/搜索