essay
hot100-滑动窗口最大值
#算法
hot100——滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
示例 2:
输入:nums = [1], k = 1
输出:[1]
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
解
func maxSlidingWindow(nums []int, k int) []int {
// que 是一个双端队列(用切片模拟),存储的是 nums 的下标(不是值!)
// 队列中下标对应的 nums 值从队首到队尾严格递减
que := []int{}
// result 存储每个窗口的最大值
result := []int{}
// 遍历数组中的每个元素
for i := 0; i < len(nums); i++ {
// 【关键1:维护队列单调性】
// 从队列尾部开始,移除所有对应值小于当前 nums[i] 的下标
// 因为这些元素既比 nums[i] 小,又在 nums[i] 左边,
// 所以在后续窗口中永远不可能成为最大值,可以安全丢弃
for len(que) > 0 && nums[que[len(que)-1]] < nums[i] {
que = que[:len(que)-1] // 弹出队尾
}
// 将当前下标 i 加入队尾
que = append(que, i)
// 【关键2:移除过期元素】
// 如果队首下标已经不在当前窗口 [i-k+1, i] 范围内(即 <= i-k),
// 说明它已滑出窗口左侧,需要从队首移除
if que[0] < i-k+1 {
que = que[1:] // 移除队首(逻辑上 O(1) 摊还)
}
// 【关键3:记录结果】
// 当 i >= k-1 时,第一个完整窗口形成(窗口包含下标 [0, ..., k-1])
// 此后每个 i 都对应一个完整窗口,队首下标 que[0] 对应的值就是当前窗口最大值
if i >= k-1 {
result = append(result, nums[que[0]])
}
}
return result
}