Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fb7ac1c

Browse files
feat: add solutions to lc problem: No.0239 (doocs#3894)
No.0239.Sliding Window Maximum
1 parent a471399 commit fb7ac1c

File tree

12 files changed

+297
-327
lines changed

12 files changed

+297
-327
lines changed

‎solution/0200-0299/0239.Sliding Window Maximum/README.md‎

Lines changed: 100 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -171,100 +171,6 @@ func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
171171
func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
172172
```
173173

174-
#### Rust
175-
176-
```rust
177-
use std::collections::VecDeque;
178-
179-
impl Solution {
180-
#[allow(dead_code)]
181-
pub fn max_sliding_window(nums: Vec<i32>, k: i32) -> Vec<i32> {
182-
// The deque contains the index of `nums`
183-
let mut q: VecDeque<usize> = VecDeque::new();
184-
let mut ans_vec: Vec<i32> = Vec::new();
185-
186-
for i in 0..nums.len() {
187-
// Check the first element of queue, if it's out of bound
188-
if !q.is_empty() && (i as i32) - k + 1 > (*q.front().unwrap() as i32) {
189-
// Pop it out
190-
q.pop_front();
191-
}
192-
// Pop back elements out until either the deque is empty
193-
// Or the back element is greater than the current traversed element
194-
while !q.is_empty() && nums[*q.back().unwrap()] <= nums[i] {
195-
q.pop_back();
196-
}
197-
// Push the current index in queue
198-
q.push_back(i);
199-
// Check if the condition is satisfied
200-
if i >= ((k - 1) as usize) {
201-
ans_vec.push(nums[*q.front().unwrap()]);
202-
}
203-
}
204-
205-
ans_vec
206-
}
207-
}
208-
```
209-
210-
#### JavaScript
211-
212-
```js
213-
/**
214-
* @param {number[]} nums
215-
* @param {number} k
216-
* @return {number[]}
217-
*/
218-
var maxSlidingWindow = function (nums, k) {
219-
let ans = [];
220-
let q = [];
221-
for (let i = 0; i < nums.length; ++i) {
222-
if (q && i - k + 1 > q[0]) {
223-
q.shift();
224-
}
225-
while (q && nums[q[q.length - 1]] <= nums[i]) {
226-
q.pop();
227-
}
228-
q.push(i);
229-
if (i >= k - 1) {
230-
ans.push(nums[q[0]]);
231-
}
232-
}
233-
return ans;
234-
};
235-
```
236-
237-
#### C#
238-
239-
```cs
240-
using System.Collections.Generic;
241-
242-
public class Solution {
243-
public int[] MaxSlidingWindow(int[] nums, int k) {
244-
if (nums.Length == 0) return new int[0];
245-
var result = new int[nums.Length - k + 1];
246-
var descOrderNums = new LinkedList<int>();
247-
for (var i = 0; i < nums.Length; ++i)
248-
{
249-
if (i >= k && nums[i - k] == descOrderNums.First.Value)
250-
{
251-
descOrderNums.RemoveFirst();
252-
}
253-
while (descOrderNums.Count > 0 && nums[i] > descOrderNums.Last.Value)
254-
{
255-
descOrderNums.RemoveLast();
256-
}
257-
descOrderNums.AddLast(nums[i]);
258-
if (i >= k - 1)
259-
{
260-
result[i - k + 1] = descOrderNums.First.Value;
261-
}
262-
}
263-
return result;
264-
}
265-
}
266-
```
267-
268174
<!-- tabs:end -->
269175

270176
<!-- solution:end -->
@@ -273,20 +179,11 @@ public class Solution {
273179

274180
### 方法二:单调队列
275181

276-
这道题也可以使用单调队列来解决。时间复杂度 $O(n),ドル空间复杂度 $O(k)$
182+
求滑动窗口的最大值,一种常见的方法是使用单调队列
277183

278-
单调队列常见模型:找出滑动窗口中的最大值/最小值。模板:
184+
我们可以维护一个从队头到队尾单调递减的队列 $q,ドル队列中存储的是元素的下标。遍历数组 $\textit{nums},ドル对于当前元素 $\textit{nums}[i],ドル我们首先判断队头元素是否滑出窗口,如果滑出窗口则将队头元素弹出。然后我们将当前元素 $\textit{nums}[i]$ 从队尾开始依次与队尾元素比较,如果队尾元素小于等于当前元素,则将队尾元素弹出,直到队尾元素大于当前元素或者队列为空。然后将当前元素的下标加入队列。此时队列的队头元素即为当前滑动窗口的最大值,注意,我们将队头元素加入结果数组的时机是当下标 $i$ 大于等于 $k-1$ 时。
279185

280-
```python
281-
q = deque()
282-
for i in range(n):
283-
# 判断队头是否滑出窗口
284-
while q and checkout_out(q[0]):
285-
q.popleft()
286-
while q and check(q[-1]):
287-
q.pop()
288-
q.append(i)
289-
```
186+
时间复杂度 $O(n),ドル空间复杂度 $O(k)$。其中 $n$ 为数组 $\textit{nums}$ 的长度。
290187

291188
<!-- tabs:start -->
292189

@@ -297,10 +194,10 @@ class Solution:
297194
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
298195
q = deque()
299196
ans = []
300-
for i, v in enumerate(nums):
301-
if q and i - k +1>q[0]:
197+
for i, x in enumerate(nums):
198+
if q and i - q[0]>= k:
302199
q.popleft()
303-
while q and nums[q[-1]] <= v:
200+
while q and nums[q[-1]] <= x:
304201
q.pop()
305202
q.append(i)
306203
if i >= k - 1:
@@ -316,16 +213,16 @@ class Solution {
316213
int n = nums.length;
317214
int[] ans = new int[n - k + 1];
318215
Deque<Integer> q = new ArrayDeque<>();
319-
for (int i = 0, j =0; i < n; ++i) {
320-
if (!q.isEmpty() && i - k +1>q.peekFirst()) {
216+
for (int i = 0; i < n; ++i) {
217+
if (!q.isEmpty() && i - q.peekFirst()>= k) {
321218
q.pollFirst();
322219
}
323220
while (!q.isEmpty() && nums[q.peekLast()] <= nums[i]) {
324221
q.pollLast();
325222
}
326-
q.offer(i);
223+
q.offerLast(i);
327224
if (i >= k - 1) {
328-
ans[j++] = nums[q.peekFirst()];
225+
ans[i - k +1] = nums[q.peekFirst()];
329226
}
330227
}
331228
return ans;
@@ -342,15 +239,15 @@ public:
342239
deque<int> q;
343240
vector<int> ans;
344241
for (int i = 0; i < nums.size(); ++i) {
345-
if (!q.empty() && i - k + 1 > q.front()) {
242+
if (q.size() && i - q.front() >= k) {
346243
q.pop_front();
347244
}
348-
while (!q.empty() && nums[q.back()] <= nums[i]) {
245+
while (q.size() && nums[q.back()] <= nums[i]) {
349246
q.pop_back();
350247
}
351248
q.push_back(i);
352249
if (i >= k - 1) {
353-
ans.emplace_back(nums[q.front()]);
250+
ans.push_back(nums[q.front()]);
354251
}
355252
}
356253
return ans;
@@ -363,22 +260,105 @@ public:
363260
```go
364261
func maxSlidingWindow(nums []int, k int) (ans []int) {
365262
q := []int{}
366-
for i, v := range nums {
367-
if len(q) > 0 && i-k+1 > q[0] {
263+
for i, x := range nums {
264+
if len(q) > 0 && i-q[0] >= k {
368265
q = q[1:]
369266
}
370-
for len(q) > 0 && nums[q[len(q)-1]] <= v {
267+
for len(q) > 0 && nums[q[len(q)-1]] <= x {
371268
q = q[:len(q)-1]
372269
}
373270
q = append(q, i)
374271
if i >= k-1 {
375272
ans = append(ans, nums[q[0]])
376273
}
377274
}
378-
return ans
275+
return
276+
}
277+
```
278+
279+
#### TypeScript
280+
281+
```ts
282+
function maxSlidingWindow(nums: number[], k: number): number[] {
283+
const ans: number[] = [];
284+
const q = new Deque();
285+
for (let i = 0; i < nums.length; ++i) {
286+
if (!q.isEmpty() && i - q.front()! >= k) {
287+
q.popFront();
288+
}
289+
while (!q.isEmpty() && nums[q.back()!] <= nums[i]) {
290+
q.popBack();
291+
}
292+
q.pushBack(i);
293+
if (i >= k - 1) {
294+
ans.push(nums[q.front()!]);
295+
}
296+
}
297+
return ans;
298+
}
299+
```
300+
301+
#### Rust
302+
303+
```rust
304+
use std::collections::VecDeque;
305+
306+
impl Solution {
307+
pub fn max_sliding_window(nums: Vec<i32>, k: i32) -> Vec<i32> {
308+
let k = k as usize;
309+
let mut ans = Vec::new();
310+
let mut q: VecDeque<usize> = VecDeque::new();
311+
312+
for i in 0..nums.len() {
313+
if let Some(&front) = q.front() {
314+
if i >= front + k {
315+
q.pop_front();
316+
}
317+
}
318+
while let Some(&back) = q.back() {
319+
if nums[back] <= nums[i] {
320+
q.pop_back();
321+
} else {
322+
break;
323+
}
324+
}
325+
q.push_back(i);
326+
if i >= k - 1 {
327+
ans.push(nums[*q.front().unwrap()]);
328+
}
329+
}
330+
ans
331+
}
379332
}
380333
```
381334

335+
#### JavaScript
336+
337+
```js
338+
/**
339+
* @param {number[]} nums
340+
* @param {number} k
341+
* @return {number[]}
342+
*/
343+
var maxSlidingWindow = function (nums, k) {
344+
const ans = [];
345+
const q = new Deque();
346+
for (let i = 0; i < nums.length; ++i) {
347+
if (!q.isEmpty() && i - q.front() >= k) {
348+
q.popFront();
349+
}
350+
while (!q.isEmpty() && nums[q.back()] <= nums[i]) {
351+
q.popBack();
352+
}
353+
q.pushBack(i);
354+
if (i >= k - 1) {
355+
ans.push(nums[q.front()]);
356+
}
357+
}
358+
return ans;
359+
};
360+
```
361+
382362
<!-- tabs:end -->
383363

384364
<!-- solution:end -->

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /