方法一:暴力法 ,时间复杂度O((n-k) * k)
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if(nums.empty() || k<=1) return nums;
vector<int> subMax(nums.size()-k+1);
int i = 0;
for(int j = k-1; j < nums.size(); j++) {
int temp = nums[i];
for (int l = i+1; l <= j; l++) {
if(temp < nums[l]) temp = nums[l];
}
subMax[i] = temp;
i++;
}
return subMax;
}
};
方法二:
采用单调队列作为辅助数据结构,每移动一次,就是在一堆数中去掉一个元素,再加一个元素。需要及时更新队头,删除出窗的元素索引,队尾元素单调入队,就是比它小的先弹出去再让它入队。这样队头始终保持最大值。
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if(nums.empty() || k<=1) return nums;
vector<int> result;
deque<int> q;
//初始化
q.push_back(0);
for(int i=1; i<k; i++) {
while(!q.empty() && nums[i] > nums[q.back()]) {
q.pop_back();
}
q.push_back(i);
}
result.push_back(nums[q.front()]);
//开始循环,i是每个滑动之后的起始索引
for(int i=1; i<nums.size()-k+1; i++) {
if(q.front() < i) {
q.pop_front();
}
while(!q.empty() && nums[i+k-1] > nums[q.back()]) {
q.pop_back();
}
q.push_back(i+k-1);
result.push_back(nums[q.front()]);
}
return result;
}
};
Python3实现:参考官方的最优解法
from collections import deque
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
if len(nums) < 1 or k <= 1:
return nums
n = len(nums)
deq = deque()
def deque_fresh(i): #i是窗口结束位置的索引
if deq and deq[0] == i-k:
deq.popleft()
while deq and nums[i] > nums[deq[-1]]:
deq.pop()
deq.append(i)
for i in range(k):
deque_fresh(i)
#deq.push(i)
result = [nums[deq[0]]]
for i in range(k, n, 1):
deque_fresh(i)
#deq.push(i)
result.append(nums[deq[0]])
return result