LeetCode 239. 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. Return the max sliding window.

Example:

Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
Output: [3,3,5,5,6,7]
Explanation:
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

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

Follow up:
Could you solve it in linear time?

解析:找到滑动窗口中的最大值。对于一个数组,设置长度为k的滑动窗口,从左到右开始滑动,每次输出滑动窗口中的最大值。

解法1:

采用优先队列priority_queue,由大到小排序,队列中存放的是一个pair,分别是数字和对应的下标。挨个元素遍历,如果队列首元素下标<=i-k,即已经滑出窗口,则从队列中pop出来。具体代码如下:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> result;
        priority_queue<pair<int, int>> pq;
        for(int i=0; i < nums.size(); i++)
        {
            while(!pq.empty() && pq.top().second<= i-k)
                pq.pop();
            pq.push({nums[i], i});
            if(i >= k-1)
                result.push_back(pq.top().first);
        }
        return result;
    }
};

解法2:

采用双向队列存放元素,是用双向队列保存数字的下标,遍历整个数组,如果此时队列的首元素是 i-k 的话,表示此时窗口向右移了一步,则移除队首元素。然后比较队尾元素和将要进来的值,如果小的话就都移除,然后此时我们把队首元素加入结果中即可。代码如下:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> result;
        deque<int> de;
        for(int i=0; i < nums.size(); i++)
        {
            if(!de.empty() && de.front() == i-k)
                de.pop_front();
            while(!de.empty() && nums[de.back()] < nums[i])
                de.pop_back();
            de.push_back(i);
            if(i >= k-1)
                result.push_back(nums[de.front()]);
        }
        return result;
    }
};

Add a Comment

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据