You are given an array of integers 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 1:
Input: nums = [1,3,-1,-3,5,3,6,7], 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
Example 2:
Input: nums = [1], k = 1
Output: [1]
Example 3:
Input: nums = [1,-1], k = 1
Output: [1,-1]
Example 4:
Input: nums = [9,11], k = 2
Output: [11]
Example 5:
Input: nums = [4,-2], k = 2
Output: [4]
Constraints:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
题目链接:https://leetcode.com/problems/sliding-window-maximum/
思路:最简单的思路是O(kn),所以复杂度还是太大了。这个方法只要O(n)
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> ans;
deque<int> deq;
for (int i = 0; i < nums.size(); ++i)
{
// make deq descending 单调减的 deque
while (deq.size() > 0 && nums[deq.back()] < nums[i])
{
deq.pop_back();
}
deq.push_back(i);
// push max value
if (deq.size() > 0 && i >= k-1)//i >= k-1,够一个窗口了,可以选窗口里的最大值了
{
ans.push_back(nums[deq.front()]);
}
// remove num out of window
if (deq.size() > 0 && deq.front() <= i-k+1)//为下一次做准备,因为下一次是 i+1, i+1-k不包含在下次窗口里
{
deq.pop_front();
}
}
return ans;
}
};
java版本
class Solution {
/**
2024.6.16
用一个双端队列记录每个窗口里元素从大到小的下标值,是单调队列,peekFirst是头,peekLast是尾;
i从0开始遍历数组,当队列头的下标等于 i-k,表明不是这个窗口里的值了,所以剔除掉;
然后更新队列尾部,如果元素nums[i]比队列尾部大,就一直把踢掉队列尾部元素,保持队列单调性;
然后当i大于等于i-k,表明已经足够k个元素了,满足一个窗口了
*/
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums == null || nums.length==0){
return new int[0];
}
int[] res=new int[nums.length-k+1];
// LinkedList 是 Deque 接口的一个具体实现类
// pollFirst() 从队列的头部移除元素
// peekFirst() 从队列的头部获取元素
// addLast() 在队列的尾部添加元素
// peeklast() 从队列的尾部获取元素
Deque<Integer> deq=new LinkedList<>();
for(int i=0;i<nums.length;i++){
if(!deq.isEmpty() && deq.peekFirst()==i-k){
deq.pollFirst();
}
while(!deq.isEmpty() && nums[deq.peekLast()]<nums[i]){
deq.pollLast();
}
deq.addLast(i);
if(i>=k-1){
res[i-k+1]=nums[deq.peekFirst()];
}
}
return res;
}
}