59-01 滑动窗口的最大值
题目
给定一个数组和滑动窗口的大小,请找出所有滑动窗口的最大值。例如,输入数组{2,3,4,2,6,2,5,1}和数字3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}。
C++题解
借助双向队列,对于新来的元素k,将其与队列中元素比较:
- 若队列中有元素比k小,直接将之前比k小的元素移除队列(因为不可能再成为后面滑动窗口的最大值),压入k。
- 若队列中元素x比k大,则根据下标检测x是否在窗口内,如果不在则移除队列,压入k。
注意:
- 队列的第一个元素是滑动窗口的最大值;
- 队列存放的是数字在数组中的下标,而不是数值。
举例说明:
1、将2压入队列
2、3比2大,弹出2,压入3
3、4比3大,弹出3,压入4
4、2比4小,4还在窗口内,保留4,压入2
5、6比4和2都大,因此弹出4和2,压入6
6、2比6小,6在窗口内,保留6,压入2
7、5比2大,比6小,且6还在窗口内,弹出2,压入5
8、1比6和5都小,但是6不在窗口内,6弹出,压入1
class Solution {
public:
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> res;
deque<int> data;
for (unsigned int i = 0;i < num.size();i++)
{
// 如果辅助队列非空,并且队尾的元素小于当前的值,那么就将队尾的元素出队
// 因为它小于当前的值,所以它不可能有机会成为最大值
while(data.size() && num[data.back()] <= num[i])
data.pop_back();
// 如果当前的队首元素的位置已经超过了滑窗大小,那么应该将其从队首移出
while(data.size() && i - data.front() + 1 > size)
data.pop_front();
// 每次都将当前的值添加到队尾中
data.push_back(i);
// 滑窗大于0并且已经满足滑窗范围,那么就将当前的队首元素添加到结果中
if(size && i + 1 >= size)
res.push_back(num[data.front()]);
}
return res;
}
};
python题解
思路与C++题解一致。
# -*- coding:utf-8 -*-
class Solution:
def maxInWindows(self, num, size):
# write code here
listA = []
res = []
for i in range(len(num)):
while listA and num[listA[-1]] <= num[i]:
listA.pop()
while listA and (i - listA[0] + 1) > size:
listA.pop(0)
listA.append(i)
if size and i + 1 >= size:
res.append(num[listA[0]])
return res
注意:
- python中 list 的
pop()函数可以根据索引移除值,而默认的索引是-1,不要理解为只能移除最后一个值。


浙公网安备 33010602011771号