@@ -20,8 +20,8 @@ https://leetcode-cn.com/problems/sliding-window-maximum/
2020示例:
2121
2222输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
23- 输出: [3,3,5,5,6,7]
24- 解释:
23+ 输出: [3,3,5,5,6,7]
24+ 解释:
2525
2626 滑动窗口的位置 最大值
2727--------------- -----
@@ -45,7 +45,7 @@ https://leetcode-cn.com/problems/sliding-window-maximum/
4545
4646- 队列
4747- 滑动窗口
48-
48+
4949## 公司
5050
5151- 阿里
@@ -61,7 +61,7 @@ https://leetcode-cn.com/problems/sliding-window-maximum/
6161JavaScript:
6262
6363``` js
64- var maxSlidingWindow = function (nums , k ) {
64+ var maxSlidingWindow = function (nums , k ) {
6565 // bad 时间复杂度O(n * k)
6666 if (nums .length === 0 || k === 0 ) return [];
6767 let slideWindow = [];
@@ -76,6 +76,7 @@ var maxSlidingWindow = function(nums, k) {
7676 return ret;
7777};
7878```
79+
7980Python3:
8081
8182``` python
@@ -91,17 +92,15 @@ class Solution:
9192但是如果真的是这样,这道题也不会是 hard 吧?这道题有一个 follow up,要求你用线性的时间去完成。
9293我们可以用双端队列来完成,思路是用一个双端队列来保存` 接下来的滑动窗口可能成为最大值的数 ` 。具体做法:
9394
94-
9595- 入队列
9696
9797- 移除失效元素,失效元素有两种
9898
99- 1 . 一种是已经超出窗口范围了,比如我遍历到第4个元素 ,k = 3,那么i = 0的元素就不应该出现在双端队列中了
100- 具体就是` 索引大于 i - k + 1的元素都应该被清除 `
99+ 1 . 一种是已经超出窗口范围了,比如我遍历到第 4 个元素 ,k = 3,那么 i = 0 的元素就不应该出现在双端队列中了
100+ 具体就是` 索引大于 i - k + 1的元素都应该被清除 `
101101
1021022 . 小于当前元素都没有利用价值了,具体就是` 从后往前遍历(双端队列是一个递减队列)双端队列,如果小于当前元素就出队列 `
103103
104-
105104如果你仔细观察的话,发现双端队列其实是一个递减的一个队列。因此队首的元素一定是最大的。用图来表示就是:
106105
107106![ ] ( https://tva1.sinaimg.cn/large/007S8ZIlly1ghltxg29buj30hb0di757.jpg )
@@ -114,11 +113,10 @@ class Solution:
114113
115114## 代码
116115
117-
118116JavaScript:
119117
120118``` js
121- var maxSlidingWindow = function (nums , k ) {
119+ var maxSlidingWindow = function (nums , k ) {
122120 // 双端队列优化时间复杂度, 时间复杂度O(n)
123121 const deque = []; // 存放在接下来的滑动窗口可能成为最大值的数
124122 const ret = [];
@@ -147,17 +145,16 @@ Python3:
147145``` python
148146class Solution :
149147 def maxSlidingWindow (self , nums : List[int ], k : int ) -> List[int ]:
150- deque, res, n = [] , [], len (nums)
148+ deque, res, n = collections.deque() , [], len (nums)
151149 for i in range (n):
152150 while deque and deque[0 ] < i - k + 1 :
153- deque.pop( 0 )
151+ deque.popleft( )
154152 while deque and nums[i] > nums[deque[- 1 ]]:
155- deque.pop(- 1 )
153+ deque.pop()
156154 deque.append(i)
157- if i >= k - 1 : res.append(nums[deque[0 ]])
155+ if i >= k - 1 :
156+ res.append(nums[deque[0 ]])
158157 return res
159-
160-
161158```
162159
163160** 复杂度分析**
@@ -168,8 +165,8 @@ class Solution:
168165## 扩展
169166
170167### 为什么用双端队列
171- 因为删除无效元素的时候,会清除队首的元素(索引太小了)或者队尾(元素太小了)的元素。 因此需要同时对队首和队尾进行操作,使用双端队列是一种合乎情理的做法。
172168
169+ 因为删除无效元素的时候,会清除队首的元素(索引太小了)或者队尾(元素太小了)的元素。 因此需要同时对队首和队尾进行操作,使用双端队列是一种合乎情理的做法。
173170
174171大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。
175172大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
0 commit comments