作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://www.nowcoder.com/ta/coding-interviews
题目描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
解题方法
暴力求解
定长的滑动窗口,直接使用切片即可。但是时间复杂度高,是O(N*k).
代码:
# -*- coding:utf-8 -*-
class Solution:
def maxInWindows(self, num, size):
if not num or not size: return []
_len = len(num)
res = []
for i in range(_len - size + 1):
res.append(max(num[i : i+size]))
return res
单调递减队列
这个题是剑指offer的题目,做法挺多,我使用的是单调递减双向队列解决。
设定一个大小为k的单调递减双向队列,时刻保持队列是单调递减的,即如果从最右边加入了一个较大的数字,需要从右开始退队列,使得队列是单调递减的。如果队列的大小达到了k,则应该把队列最前面的数字删除掉。
时间复杂度是O(N).
python代码如下:
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
que = collections.deque() # [[i, num]]
res = []
for i, num in enumerate(nums):
if que and i - que[0][0] >= k:
que.popleft()
while que and que[-1][1] <= num:
que.pop()
que.append([i, num])
if i >= k - 1:
res.append(que[0][1])
return res
日期
2018 年 3 月 28 日 – 北京雾霾+沙尘暴,我的天。。