2020年3月19日
LeetCode 239. Sliding Window Maximum
C++, LeetCode, 算法, 编程
0 Comments
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;
}
};