生成窗口最大值数组

如果数组长度为N,窗口大小为w,如果做出时间复杂度O(N*w)的解法是不能让面试官满意的,本题要求面试者想出时间复杂度O(N)的实现。

本题的关键在于利用双端队列来实现窗口最大值的更新。首先生成双端队列qmax,qmax中存放数组arr中的下标。

假设遍历到arr[i], qmax的放入规则为:


1.如果qmax为空,直接把下标i放进qmax,放入过程结束。

2.如果qmax不为空,取出当前qmax队尾存放的下标,假设为j。

  • 如果arr[j]>arr[i], 直接把下标i放进qmax的队尾,放入过程结束。
  • 如果arr[j]<=arr[i],把j从qmax中弹出,继续qmax的放入规则。

 

#include<iostream>
#include<deque>
using namespace std;

template <class T>
int getArrayLen(T& array)
{
    return sizeof(array) / sizeof(array[0]);
}

int* maxWindow(int arr[], int len, int w) {
    if (arr == NULL || w < 1 || len < w) {
        return 0;
    }
    deque<int> qmax;
    int* res = new int[len - w + 1];
    if (NULL == res) {
        cout << "Memory allocated failed!" << endl;
        return NULL;
    }
    int index = 0;
    for (int i = 0; i < len; i++) {
        while (!qmax.empty() && arr[qmax.back()] <= arr[i]) {        
            qmax.pop_back();
        }
        qmax.push_back(i);
        if (qmax.front() == i - w) {
            qmax.pop_front();
        }
        if (i >= w - 1) {
            res[index++] = arr[qmax.front()];
        }
    }
    return res;
}

int main()
{
    int arr[] = { 4,3,5,4,3,3,6,7 };
    int len = getArrayLen(arr);
    int* res = maxWindow(arr, len, 3);
    for (int i = 0; i < len - 2; i++)
    {
        cout << res[i] << " ";
    }
    return 0;
}

 

posted @ 2019-07-30 20:02  木子石页  阅读(215)  评论(0编辑  收藏  举报