【LeetCode】239. Sliding Window Maximum

Sliding Window Maximum

 

Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.

For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.

Window position                Max
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

Therefore, return the max sliding window as [3,3,5,5,6,7].

Note: 
You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.

Follow up:
Could you solve it in linear time?

Hint:

  1. How about using a data structure such as deque (double-ended queue)?
  2. The queue size need not be the same as the window’s size.
  3. Remove redundant elements and the queue should store only elements that need to be considered.
 
参考fentoyal的单调队列做法,我加上一些解释。
双端队列mq存放的是二元组,
第一元素表示当前值,
第二元素表示在队列中末尾值之后,在当前值之前并且小于当前值的个数。
mq的首个二元组的第一元素表示窗口范围内的最大值。
max函数:
  返回首个二元组的第一元素
push函数:
  为了保证max函数的作用,需要从末尾开始,把小于当前值的连续二元组出队列,但是需要累加上小于当前值的数目。
pop函数:
  如果窗口在首个二元组之前还有元素,那么对队列影响就是首个二元组的计数减一。
  否则代表首个二元组就是待出队的值,出队。
 
class MonoQue
{
public:
    deque<pair<int, int> > q;
    int maxV()
    {
        return q.front().first;
    }
    void push(int n)
    {
        int count = 0;
        while(!q.empty() && q.back().first < n)
        {
            count += (q.back().second + 1);
            q.pop_back();
        }
        q.push_back(make_pair(n, count));
    }
    void pop()
    {
        if(q.front().second > 0)
            q.front().second --;
        else
            q.pop_front();
    }
};

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> ret;
        if(k == 0)
            return ret;
        MonoQue mq;
        for(int i = 0; i < k; i ++)
            mq.push(nums[i]);
        for(int i = k; i < nums.size(); i ++)
        {
            ret.push_back(mq.maxV());
            mq.pop();
            mq.push(nums[i]);
        }
        ret.push_back(mq.maxV());
        return ret;
    }
};

posted @ 2015-07-25 19:22  陆草纯  阅读(320)  评论(0编辑  收藏  举报