239. 滑动窗口最大值
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。
进阶:
你能在线性时间复杂度内解决此题吗?
分析
- 记录时机:遍历vector ,i >= k - 1时开始记录窗口中的最大值
- 获取窗口中的最大值方法:
维护一个严格递减的数据结构 |
---|
循环[i , i + k) ,比较得出最大值 O(n) |
- 采用方法二嵌套循环时间复杂度O(n2)
- 因为我们只需要窗口中的最大值,严格递减的数据结构使用栈的特性,比当前遍历元素小的栈元素出栈,然后将当前遍历元素入栈,栈底为我们需要的最大值;在有序的数据结构中,随着窗口的移动,利用到队列的特性,当队首不在窗口中时,要把队首删除,维护有效的严格递减数据结构。双边队列deque满足上述栈和队列的所有能力,选用这个数据结构使问题简化,并降低时间复杂度为O(n)。
- 本题中,双边队列中可以存储数组下标,也可以存储数据元素。
C++实现
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
if(k == 0) return res;
std::deque<int> win;
for(int i = 0;i < nums.size();++i)
{
//严格递减,使用栈的特性
while(!win.empty() && nums[i] > nums[win.back()])
{
win.pop_back();
}
win.push_back(i);
//当队首不在窗口中时,要把队首删除
if(i >= k && win.front() == i - k)
{
win.pop_front();
}
//开始记录窗口中的最大值的时机
if(i >= k - 1)
{
res.push_back(nums[win.front()]);
}
}
return res;
}
};
Python3
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
res = []
deq = collections.deque()
for i,num in enumerate(nums):
while deq and num > nums[deq[-1]]:
deq.pop()
deq.append(i)
if i >= k and int(deq[0]) == i - k:
deq.popleft()
if i >= k - 1:
res.append(nums[deq[0]])
return res
来源:CSDN
作者:禾中一颗树
链接:https://blog.csdn.net/vczlyz/article/details/104649759