***239. Sliding Window Maximum 滑动窗口最大值

1. 原始题目

给定一个数组 nums,有一个大小为 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口 k 内的数字。滑动窗口每次只向右移动一位。

返回滑动窗口最大值。

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7] 
解释: 

  滑动窗口的位置                最大值
---------------               -----
[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

注意:

你可以假设 总是有效的,1 ≤ k ≤ 输入数组的大小,且输入数组不为空。

进阶:

你能在线性时间复杂度内解决此题吗?

 

2. 思路

方法1.暴力法

方法2.最大堆(优先队列)

方法3.队列(核心思路:滑动窗口的最大值总是保存在队列首部,队列里面的数据总是从大到小排列。

看一下利用队列的做法:针对上面 [1,3,-1,-3,5,3,6,7], 和 k = 3定义一个队列temp=[]和存放结果的数组res=[]。

begin:

首先1进队,3进队,因为3比1大,此时1应出队,因为3比1大,1就没有机会成为窗口最大值。-1进队(实际我们保存索引)。此时temp=【1,2】,res=[3]。

然后该-3进队了,进队前先看当前队内元素数目小于k,并且对内元素都比它大,所以-3直接进队。此时temp=【1,2,3】,res=[3,3]。

然后该5进队了,进队前发现temp已经有k=3个元素了,那队首就该出去腾位置,然后在比较剩余的元素都比5小,都出对。然后5进队。此时temp=[4],res=[3,3,5]。

然后该3进队了,进队前发现队内元素数目小于k,在比较其他元素都比他大,所以3进队。此时temp=【4,5】,res=[3,3,5,5]。

然后该6进队了,进队前发现队内元素数目小于k,其他元素都比他小!都出去,6近来。此时temp=【6】,res=【3,3,5,5,6】。

然后该7进队了,进队前发现对内元素数目小于k,其他元素都比他小!都出去,7自己进来。此时temp=【7】,res=[3,3,5,5,6,7]。

end

 

此题最初没有想明白具体流程,导致一直有bug,理清楚上面的思路后就通过了。算法实现步骤如下:

假设我们已经有了一个窗口 [ ],此时我们要将窗口右移,即新的元素要进窗口,此时我们要先做两个判断

1) 判断窗口内的元素是否已经有k个了,如果=k了,此时应该将队列首元素出队。好,此时起码给我们腾出了空间允许新元素进队(队内的元素最多k个!因为窗口大小就是k)。

2)判断完之后,我们的i+1个新元素要进队了,此时要判断之前队内的元素哪些比他小,小的元素都要出队。

两个判断结束。好,一切都准备就绪了,这个第i+1元素进队,然后将队首的元素存放到结果中。

 1 class Solution:
 2     def maxSlidingWindow(self, nums, k):
 3         if not nums or k<1: return []
 4         temp = []    # 临时队列
 5         res = []     # 结果存放
 6         for i in range(len(nums)):
 7             
 8             if temp and i-temp[0]>=k:     # 判断1.是否队列的元素数目已经有k个了,若是则队首出,腾位置
 9                 temp.pop(0)
10             
11             temp = [k for k in temp if nums[k]>nums[i]]  # 判断2.当前i个元素加入后,是否队内元素没有递减排序
12                 
13             temp.append(i)     # 判断完成,索引i进队
14             if i>=k-1:         
15                 res.append(nums[temp[0]])   # 保存队首元素作为当前窗口最大值   
16             
17         return res

 

posted @ 2019-05-06 10:52  三年一梦  阅读(326)  评论(0)    收藏  举报