239_困难_滑动窗口最大值
239 滑动窗口最大值
https://leetcode.cn/problems/sliding-window-maximum/
算法1:单调递减队列
// date 2022-09-08
func maxSlidingWindow(nums []int, k int) []int {
size := len(nums)
que := NewDeque()
res := make([]int, 0, 1024)
for i := 0; i < k; i++ {
que.Push(nums[i])
}
res = append(res, que.Max())
for i := k; i < size; i++ {
que.Pop(nums[i-k])
que.Push(nums[i])
res = append(res, que.Max())
}
return res
}
type Deque struct {
queue []int
}
func NewDeque() *Deque {
return &Deque{
queue: make([]int, 0, 1024),
}
}
func (s *Deque) Push(x int) {
for len(s.queue) != 0 && x > s.queue[len(s.queue)-1] {
s.queue = s.queue[:len(s.queue)-1]
}
s.queue = append(s.queue, x)
}
func (s *Deque) Max() int {
return s.queue[0]
}
func (s *Deque) Pop(x int) {
if len(s.queue) != 0 && x == s.queue[0] {
s.queue = s.queue[1:]
}
}
算法2:滑动窗口
其实这种解法跟上面的单调递减队列是一个原理,只不过借滑动窗口的思想,由 list
充当单调递减队列。
初始化
left = right = 0
,闭区间[left, right]
表示一个固定窗口,即k个大小初始化
list
充当单调递减队列,当队列不为空且nums[right]
大于队列尾部元素时,不断地移除队尾元素增加right,扩大窗口
当窗口构造完成后,取队头元素加入结果集;增加left
// date 2022/09/29
func maxSlidingWindow(nums []int, k int) []int {
left, right := 0, 0
ans := make([]int, 0, 64)
list := make([]int, 0, 64)
// 开始构造窗口
for right < len(nums) {
// 特殊处理:因为需要保证list为单调递减队列,需要判断窗口最右边的元素
for len(list) != 0 && nums[right] > list[len(list)-1] {
list = list[:len(list)-1]
}
// 不断地增加right
list = append(list, nums[right])
right++
// 窗口构造完成,当不满足条件时,需要增加left
if right >= k {
ans = append(ans, list[0])
// 特殊处理:增加left意味着移除窗口最左边的元素,如果等于队头元素,需要从单调递减队列中移除
if list[0] == nums[left] {
list = list[1:]
}
left++
}
}
return ans
}
最后更新于