Skip to content

Commit 23e1829

Browse files
committed
1 parent 97754c6 commit 23e1829

File tree

4 files changed

+146
-0
lines changed

4 files changed

+146
-0
lines changed

Diff for: README.md

+5
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ Aha, algorithm by go. See Chinese [README.md](./README_cn.md)
8989
* [Rotate Array](src/array/rotate-array.go) [M] [I]
9090
* [Group Anagrams](src/array/group-anagrams.go) [M] [I]
9191
* [K-th Largest Element In An Array](src/array/kth-largest-element-in-an-array.go) [M] [I]
92+
* [Sliding Window Maximum](src/array/sliding-window-maximum.go) [M] [I]
9293

9394
---
9495
### List
@@ -105,6 +106,10 @@ Aha, algorithm by go. See Chinese [README.md](./README_cn.md)
105106
* [Valid Parentheses](src/stack/valid-parentheses.go) [E] [I]
106107
* [Decode String](src/stack/decode-string.go) [M]
107108

109+
---
110+
### Queue
111+
* [Sliding Window Maximum](src/array/sliding-window-maximum.go) [M] [I]
112+
108113
---
109114
### Dynamic Programming And Greedy
110115
* [Climbing Stairs](src/optimalization/climbing-stairs.go) [E] [I]

Diff for: README_cn.md

+5
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
* [旋转数组](src/array/rotate-array.go) [M] [I]
9090
* [字母异位词分组](src/array/group-anagrams.go) [M] [I]
9191
* [数组中的第K个最大元素](src/array/kth-largest-element-in-an-array.go) [M] [I]
92+
* [滑动窗口中最大值](src/array/sliding-window-maximum.go) [M] [I]
9293

9394
---
9495
### 列表
@@ -105,6 +106,10 @@
105106
* [有效的括号](src/stack/valid-parentheses.go) [E] [I]
106107
* [字符串解码](src/stack/decode-string.go) [M]
107108

109+
---
110+
### 队列
111+
* [滑动窗口中最大值](src/array/sliding-window-maximum.go) [M] [I]
112+
108113
---
109114
### 动态规划和贪心
110115
* [爬楼梯](src/optimalization/climbing-stairs.go) [E] [I]

Diff for: src/array/sliding-window-maximum.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package array
2+
3+
// https://leetcode-cn.com/problems/sliding-window-maximum/
4+
5+
// Use two stack, but time complexity is O(n^2)
6+
func maxSlidingWindow(nums []int, k int) []int {
7+
n := len(nums)
8+
var stack, help []int
9+
var ret []int
10+
for i := 0; i < n; i++ {
11+
// stack store max value, the max value is always on the top.
12+
// the element in stack sort by: min(bottom) -> max(top)
13+
for len(stack) > 0 && stack[len(stack)-1] > nums[i] {
14+
ele := stack[len(stack)-1]
15+
stack = stack[:len(stack)-1]
16+
help = append(help, ele)
17+
}
18+
stack = append(stack, nums[i])
19+
for len(help) > 0 { // restore the popped elements
20+
stack = append(stack, help[len(help)-1])
21+
help = help[:len(help)-1]
22+
}
23+
24+
if i-k >= 0 { // find the element then delete it
25+
for stack[len(stack)-1] != nums[i-k] {
26+
ele := stack[len(stack)-1]
27+
stack = stack[:len(stack)-1]
28+
help = append(help, ele)
29+
}
30+
stack = stack[:len(stack)-1]
31+
for len(help) > 0 { // restore
32+
stack = append(stack, help[len(help)-1])
33+
help = help[:len(help)-1]
34+
}
35+
}
36+
if len(stack) >= k {
37+
// top of stack is the window maximum
38+
ret = append(ret, stack[len(stack)-1])
39+
}
40+
}
41+
return ret
42+
}
43+
44+
// The above solution problem: we do some useless stack push and pop, there is no need help stack.
45+
func maxSlidingWindowOptimizeWithDequeue(nums []int, k int) []int {
46+
n := len(nums)
47+
var dequeue []int
48+
var ret []int
49+
for i := 0; i < n; i++ {
50+
// dequeue sort the elements in window from max(left) to min(right).
51+
// When we enqueue the current nums[i], we will discard all elements small than nums[i], because the current window's
52+
// maximum elements must in [max, ..., nums[i]].
53+
for len(dequeue) > 0 && dequeue[len(dequeue)-1] < nums[i] {
54+
dequeue = dequeue[:len(dequeue)-1] // pop end
55+
}
56+
dequeue = append(dequeue, nums[i])
57+
if i-k+1 >= 0 {
58+
// if dequeue[0] == nums[i-k]
59+
if i-k >= 0 && dequeue[0] == nums[i-k] {
60+
dequeue = dequeue[1:] // pop top
61+
}
62+
ret = append(ret, dequeue[0])
63+
}
64+
}
65+
return ret
66+
}

Diff for: src/array/sliding-window-maximum_test.go

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package array
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestMaxSlidingWindow(t *testing.T) {
9+
nums := []int{1, 3, -1, -3, 5, 3, 6, 7}
10+
actual, expected := maxSlidingWindow(nums, 3), []int{3, 3, 5, 5, 6, 7}
11+
if !reflect.DeepEqual(actual, expected) {
12+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
13+
}
14+
15+
nums = []int{1, 3, 2, 4, 5, 3, 6, 7}
16+
actual, expected = maxSlidingWindow(nums, 3), []int{3, 4, 5, 5, 6, 7}
17+
if !reflect.DeepEqual(actual, expected) {
18+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
19+
}
20+
21+
nums = []int{1}
22+
actual, expected = maxSlidingWindow(nums, 1), []int{1}
23+
if !reflect.DeepEqual(actual, expected) {
24+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
25+
}
26+
}
27+
28+
func TestMaxSlidingWindowOptimizeWithDequeue(t *testing.T) {
29+
nums := []int{1, 3, -1, -3, 5, 3, 6, 7}
30+
actual, expected := maxSlidingWindowOptimizeWithDequeue(nums, 3), []int{3, 3, 5, 5, 6, 7}
31+
if !reflect.DeepEqual(actual, expected) {
32+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
33+
}
34+
35+
nums = []int{1, 3, 2, 4, 5, 3, 6, 7}
36+
actual, expected = maxSlidingWindowOptimizeWithDequeue(nums, 3), []int{3, 4, 5, 5, 6, 7}
37+
if !reflect.DeepEqual(actual, expected) {
38+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
39+
}
40+
41+
nums = []int{1}
42+
actual, expected = maxSlidingWindowOptimizeWithDequeue(nums, 1), []int{1}
43+
if !reflect.DeepEqual(actual, expected) {
44+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
45+
}
46+
47+
nums = []int{1, -1}
48+
actual, expected = maxSlidingWindowOptimizeWithDequeue(nums, 1), []int{1, -1}
49+
if !reflect.DeepEqual(actual, expected) {
50+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
51+
}
52+
53+
nums = []int{1, -1, 1}
54+
actual, expected = maxSlidingWindowOptimizeWithDequeue(nums, 2), []int{1, 1}
55+
if !reflect.DeepEqual(actual, expected) {
56+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
57+
}
58+
59+
nums = []int{1, -1, -1}
60+
actual, expected = maxSlidingWindowOptimizeWithDequeue(nums, 1), []int{1, -1, -1}
61+
if !reflect.DeepEqual(actual, expected) {
62+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
63+
}
64+
65+
nums = []int{1, -1, -1}
66+
actual, expected = maxSlidingWindowOptimizeWithDequeue(nums, 2), []int{1, -1}
67+
if !reflect.DeepEqual(actual, expected) {
68+
t.Errorf("expected is [%v], actual is [%v]", expected, actual)
69+
}
70+
}

0 commit comments

Comments
 (0)