
代码——单调队列:
- 单调队列 q 用来记录当前滑动窗口的单调递减队列,其中如果新加进来的元素更大,直接将比它小的元素弹出,因为是新加进来的所以下标更靠后,所以队列前面比它小,下标还靠前的元素就没有存在的价值了
- 我们的 push 函数做的就是上面的功能,每次压入队列的元素和队尾元素进行比较,不停的将队尾比它小的元素弹出直到队尾元素更大或长度为0,长度为0自然就是指队列所有的元素都失去了价值。因为出现了一个比他们更大且更靠后的元素出现
- 第一个for,初始化队列,将第一个滑动窗口的值依次压入队列,
- 新建ans切片,切片的容量自然是
n-k+1,然后将ans的第一个元素ans[0] = nums[q[0]],赋值
- for,i 从 k 开始以此将新的元素压入队列,二层 for 判断当前队列的第一个元素是否有效,无效则弹出,当然这里的 for 可以直接写为 if,因为 i 是一个一个加大的,下一个队列元素一定满足条件
- 最后随着每次维护单调队列后每次将第一个元素加给ans,
- 因为要判断队首元素是否有效,所以我们队列存到是下标,所以取出下标后记得根据nums得到值
func maxSlidingWindow(nums []int, k int) []int {
q := make([]int, 0)
push := func(i int) {
for len(q) > 0 && nums[i] >= nums[q[len(q)-1]] {
q = q[:len(q)-1]
}
q = append(q, i)
}
for i := 0; i < k; i++ {
push(i)
}
n := len(nums)
ans := make([]int, 1, n-k+1)
ans[0] = nums[q[0]]
for i := k; i < n; i++ {
push(i)
for q[0] <= i-k {
q = q[1:]
}
ans = append(ans, nums[q[0]])
}
return ans
}