说来惭愧,这个题目我个人死磕了四天才最终理解。感谢这个视频,最终让我理解透了。还好没放弃,四天换来理解,也可以了。重点是要在双端队列中放入元素的索引值,而不是元素值本身

解题思路:

1. 定义一个双端队列,在这里用数组模拟
2. 当前元素同双端队列的尾部元素做比较,如果小,则出队,要一直出到队列为空,或者尾部元素大于当前元素
3. 满足第二步的条件后,将当前元素的索引放入双端队列
4. 因为窗口是滑动,要判断放入队列的索引值是否还有效,无效则出队
5. 达到窗口大小后,每次从队列的头部取数据即可,此时的头部值就是当前窗口的最大值

go示例代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
func maxSlidingWindow(nums []int, k int) []int {
    // 队列为1,空,或者K为1时,直接原样返回即可
	if len(nums) <= 1 || k == 1 {
		return nums
	}
	result := make([]int, 0)
	// queue里面记录的是索引
	queue := make([]int, 0)
	left := 0
	for i, v := range nums {
		// 左指针是否移动
		if i > k - 1 {
			left += 1
		}
		// 往queue里面加数据。新元素要大于尾部元素
		// queue[len(queue) - 1] 取queue的最后一个元素在nums的索引值
		// 所以元素值就是nums[queue[len(queue)-1]]
		for len(queue) > 0 && v > nums[queue[len(queue)-1]] {
			queue = queue[:len(queue)-1]
		}
        // 出完之后,就可以将当前元素的索引入队了
		queue = append(queue, i)
        
		// queue头部的索引是否还有效,因为指针移动,值不在滑动窗口内,就要失效
		if queue[0] < left {
			queue = queue[1:]
		}
        // 达到窗口大小后,就可以往结果集里面放数据。queue存储的是索引值
		if i >= k - 1 {
			result = append(result, nums[queue[0]])
		}
	}
	return result
}