单调栈

利用单调栈寻找当前值在数组中的某段作为最小(大)值左可扩展的最大距离

时间复杂度为O(n)。遍历原数组,维护单调栈。以当前数在数组某一段中作为最小值为例:
先找向右可扩展的最远编号,按从前往后的顺序数组中的值进栈,如果新进值大于栈顶元素值,进栈。否则一直删除栈顶元素一直到当前编号可以入栈(大于栈顶元素)。在每个元素出栈的时候,就是每个元素可向右扩展的最远距离的时候,记录下来。找向左扩展最远编号则从右向左以相同方式找。
作为最大值找,相同


a: 2 1 5 3 7 2 8
l : 1 1 3 3 5 3 7
r : 1 7 3 5 5 7 7

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
const int maxn = 100000 + 10;

int n;
long long a[maxn], l[maxn], r[maxn];

int main()
{
    while(scanf("%d", &n) != EOF && n){
        for(int i = 1; i <= n; i++) scanf("%I64d", &a[i]);

        stack<int> s;
        for(int i = 1; i <= n; i++){
            if(s.empty() || a[s.top()] <= a[i]) s.push(i); //作为最小值,并且如果相等可继续扩展,(可修改)
            else{
                while(!s.empty() && a[s.top()] > a[i]){
                    r[s.top()] = i - 1;
                    s.pop();
                }
                s.push(i);
            }
        }
        while(!s.empty()){
            r[s.top()] = n;
            s.pop();
        }

        for(int i = n; i > 0; i--){
            if(s.empty() || a[s.top()] <= a[i]) s.push(i);
            else{
                while(!s.empty() && a[s.top()] > a[i]){
                    l[s.top()] = i + 1;
                    s.pop();
                }
                s.push(i);
            }
        }
        while(!s.empty()){
            l[s.top()] = 1;
            s.pop();
        }

        printf("\n");
        for(int i = 1; i <= n; i++) printf("%I64d ",l[i]); printf("\n");
        for(int i = 1; i <= n; i++) printf("%I64d ",r[i]); printf("\n");
    }
    return 0;
}
posted @ 2017-07-02 14:40  />.<\  阅读(238)  评论(0编辑  收藏  举报