Sliding Window Maximum
HardThe problem
Given a list of numbers and a window size k, slide a window of k numbers from the left end to the right end of the list, one step at a time. Return a list with the biggest number inside the window at each step.
- Example 1Input: nums = [4, 2, 12, 3, 8, 1], k = 3Output: [12, 12, 12, 8]
The windows are [4,2,12], [2,12,3], [12,3,8] and [3,8,1]. Their biggest numbers are 12, 12, 12 and 8.
- Example 2Input: nums = [5], k = 1Output: [5]
One window with one number.
- 1 ≤ nums.length ≤ 100,000
- 1 ≤ k ≤ nums.length
- -10,000 ≤ nums[i] ≤ 10,000
Write it in Go. Try for about 20 minutes on paper first, then open one hint at a time.
Try it here
Write Go. Common packages like fmt and sort are imported for you. Keep the function name and inputs the same.
Hints, one at a time
Nudge
When a new number arrives, which numbers in the window can never be the maximum again?
The idea
Keep a deque of indices with decreasing values: pop from the back while smaller than the new value, pop from the front when it leaves the window. The front is the max.
Target: O(n) time, O(k) space
Go function shape
func maxSlidingWindow(nums []int, k int) []intReference solution
Tested with go test. Try it yourself first, then compare.
// MaxSlidingWindow: keep a deque of indexes whose values decrease from front to back.
// A smaller value behind a bigger newcomer can never be the maximum again, so it is dropped.
func MaxSlidingWindow(nums []int, k int) []int {
var dq, out []int
for i, v := range nums {
for len(dq) > 0 && nums[dq[len(dq)-1]] <= v {
dq = dq[:len(dq)-1] // drop smaller values from the back
}
dq = append(dq, i)
if dq[0] <= i-k {
dq = dq[1:] // the front index slid out of the window
}
if i >= k-1 {
out = append(out, nums[dq[0]])
}
}
return out
}