输入: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 思路分析 题目中提到了滑动窗口,我们先以示例为例看下什么是滑动窗口? 在示例中,我们从数组中第一个元素开始遍历,由于窗口的大小是3,因此当遍历到第三个元素时,窗口就形成了。 △ 窗口形成 之后,继续遍历元素时,为了保持窗口的大小为3,左侧元素就需要从窗口中剔除。这样使得窗口一直在向右移动,直到考察到最后一个元素结束,这就是所谓的滑动窗口。 △ 窗口滑动 在上述滑动窗口形成及移动的过程中,我们注意到元素是从窗口的右侧进入的,然后由于窗口大小是固定的,因此多余的元素是从窗口左侧移除的。一端进入,另一端移除,这不就是队列的性质吗?所以,该题目可以借助队列来求解。 题目要求是返回每个窗口中的最大值。那么这个如何解决呢? 我们以数组{5, 3, 4, 1},窗口大小k=3来进行说明。这里我们规定窗口右侧边界为right,左侧边界为left,其值为元素下标。 然后,开始遍历nums = {5, 3, 4, 1}。当right指向第一个元素5时,此时队列为空,将第一个元素5入队。 △ 元素5入队 继续考察第二个元素3,此时3小于队列末尾的元素5,因此元素3入队,以便看其是否是下一个窗口的最大值。这时队列中元素从队首到队尾是递减的。 △ 元素3入队 接着考察{5, 3, 4, 1}中的第三个元素4,此时4大于队尾元素3,这表明元素3不可能是窗口「5 3 4」中的最大元素,因此需要将其从队列移除。但队首有元素5存在,因此不能将其从队首移除,那怎么办呢?我们可以将其从队尾移除。 对于这种一端既可以有元素入队,又有元素出队的队列,称之为双向队列。 队尾元素3出队之后,由于新的队尾元素5大于当前考察元素4,因此元素4入队,以便看其是否是下一个窗口的最大值。 当元素4入队之后,我们发现这时,队列中元素从队首到队尾依旧是递减的。我们把从队首到队尾单调递减或递增的队列称之为单调队列。 △ 元素3出队,元素4入队 接着,考察第四个元素1,此时元素1小于队尾元素4,因此元素1入队。 △ 元素1入队 但这时,窗口内有4个元素,而我们这里规定窗口大小是3,因此,需要缩小窗口左边界left。 在缩小窗口左边界left后,意味着元素5已经不再窗口内了,因此,队首元素5需要出队。也就是说,当队首元素在原数组中的下标小于窗口左边界时,队首元素就需要移除队列。 △ 缩小左边界left,队首元素5出队 至此,该题目的求解思路就清晰了,具体如下:
遍历给定数组中的元素,如果队列不为空且当前考察元素大于等于队尾元素,则将队尾元素移除。直到,队列为空或当前考察元素小于新的队尾元素; 当队首元素的下标小于滑动窗口左侧边界left时,表示队首元素已经不再滑动窗口内,因此将其从队首移除。 由于数组下标从0开始,因此当窗口右边界right+1大于等于窗口大小k时,意味着窗口形成。此时,队首元素就是该窗口内的最大值。

今天的分享就到这里了 错误或不足之处 欢迎留言指出 下一篇我们将学习新的内容,敬请期待