Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Return the max sliding window.

Example:

Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
Output: [3,3,5,5,6,7]
Explanation:

Window position Max
--------------- -----
[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

Note: 
You may assume k is always valid, 1 ≤ k ≤ input array's size for non-empty array.

Follow up:
Could you solve it in linear time?

思路

咋一看不知道题目要干嘛,其实求的是窗口从左往右滑动过程中,返回窗口中元素的最大值。比如上面Max的那一列是 3 3 5 5 6 7,那么返回的就是这个。

感觉直接遍历好像就可以了诶,不过应该会超时。而且提示我们用O(n)复杂度内解题了,看了下别人的解法,使用的是双向队列deque,保存数组元素的索引,遍历整个数组。

We scan the array from 0 to n-1, keep "promising" elements in the deque. The algorithm is amortized O(n) as each element is put and polled once.

At each i, we keep "promising" elements, which are potentially max number in window [i-(k-1),i] or any subsequent window. This means

  1. If an element in the deque and it is out of i-(k-1), we discard them. We just need to poll from the head, as we are using a deque and elements are ordered as the sequence in the array

  2. Now only those elements within [i-(k-1),i] are in the deque. We then discard elements smaller than a[i] from the tail. This is because if a[x] <a[i] and x<i, then a[x] has no chance to be the "max" in [i-(k-1),i], or any other subsequent window: a[i] would always be a better candidate.

  3. As a result elements in the deque are ordered in both sequence in array and their value. At each step the head of the deque is the max element in [i-(k-1),i]

对于每个索引i位置,它都有可能是窗口[i-(k-1),i]中的那个最大值,以题目中的例子来说明,假如i=4, 那么窗口[2, 4],即索引 2,3,4位置构成的窗口。位置4可能是这个窗口中的最大值,或者是后面窗口的最大值(因为向右滑动时还包含在里面)。这表明:

1. 如果当前队列中的索引不在窗口[2, 4]的范围内,那么丢弃它。

2. 如果现在队列中的索引只有当前窗口里面[i-(k-1),i]的,那么从尾部开始丢弃掉比a[i]小的元素,这是因为如果 a[x]<a[i] 并且 x<i,那么a[x] 不可能是 [i-(k-1), i] 中的最大值,并且在后面的窗口中也不可能是最大的,因为a[i]是更好的选择。(因为当前的索引,也就是从 i-(k-1)到i都被限制在一个窗口里了)

3. 因为每次的滑动窗口所选择的出的最大元素在队列中是按照他们的数组索引和值排序的,所以每一不这个deque的头就是 [i-(k-1),i] 中的最大元素。

代码

public int[] maxSlidingWindow(int[] a, int k) {
if (a == null || k <= 0) {
return new int[0];
}
int n = a.length;
int[] r = new int[n-k+1];
int ri = 0;
// store index
Deque<Integer> q = new ArrayDeque<>(); //双端队列的用法
for (int i = 0; i < a.length; i++) {
// 将不在当前窗口 i-k+1 到 i 内的索引移除
while (!q.isEmpty() && q.peek() < i - k + 1) {
q.poll(); // 弹出队列中的第一元素(头部,最左边)
}
// 从尾部(队列右边)remove smaller numbers in k range as they are useless
while (!q.isEmpty() && a[q.peekLast()] < a[i]) {
q.pollLast();
}
// q contains index... r contains content
q.offer(i);
if (i >= k - 1) {  // 只需要判断i-k+1>0即可,因为只有一开始不够k个元素
r[ri++] = a[q.peek()]; // 经过上面处理,队头是当前窗口中的最大元素
}
}
return r;
}

LeetCode239. Sliding Window Maximum的更多相关文章

  1. leetcode面试准备:Sliding Window Maximum

    leetcode面试准备:Sliding Window Maximum 1 题目 Given an array nums, there is a sliding window of size k wh ...

  2. 【LeetCode】239. Sliding Window Maximum

    Sliding Window Maximum   Given an array nums, there is a sliding window of size k which is moving fr ...

  3. 【刷题-LeetCode】239. Sliding Window Maximum

    Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving from ...

  4. [Swift]LeetCode239. 滑动窗口最大值 | Sliding Window Maximum

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

  5. Sliding Window Maximum 解答

    Question Given an array of n integer with duplicate number, and a moving window(size k), move the wi ...

  6. Sliding Window Maximum

    (http://leetcode.com/2011/01/sliding-window-maximum.html) A long array A[] is given to you. There is ...

  7. Sliding Window Maximum LT239

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

  8. LeetCode题解-----Sliding Window Maximum

    题目描述: Given an array nums, there is a sliding window of size k which is moving from the very left of ...

  9. [LeetCode] Sliding Window Maximum 滑动窗口最大值

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

随机推荐

  1. 洛谷 P2898 [USACO08JAN]haybale猜测Haybale Guessing 解题报告

    [USACO08JAN]haybale猜测Haybale Guessing 题目描述 给一段长度为\(n\),每个位置上的数都不同的序列\(a[1\dots n]\)和\(q\)和问答,每个问答是\( ...

  2. Educational Codeforces Round 60 (Rated for Div. 2) 题解

    Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...

  3. POJ---3463 Sightseeing 记录最短路和次短路的条数

    Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9247   Accepted: 3242 Descr ...

  4. SSH 指定密钥,连接远程服务器。

    ssh -i /root/.ssh/private.pem user@192.168.1.100 -p 7744 如上, /root/.ssh/private.pem :密钥文件路径user@192. ...

  5. 在IIS中寄存服务

    http://blog.csdn.net/songyefei/article/details/7381595 第三篇 在IIS中寄宿服务 通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型 ...

  6. JS学习之数组

  7. MyBatis框架的使用及源码分析(八) MapperMethod

    从 <MyBatis框架中Mapper映射配置的使用及原理解析(七) MapperProxy,MapperProxyFactory> 文中,我们知道Mapper,通过MapperProxy ...

  8. 梳排序Comb sort

    梳排序还是基于冒泡排序,与冒泡不同的是,梳排序比较的是固定距离处的数的比较和交换,类似希尔那样 这个固定距离是待排数组长度除以1.3得到近似值,下次则以上次得到的近似值再除以1.3,直到距离小至3时, ...

  9. 策略模式 C#

    策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 抽象策略角色: 策略类,通常由一个接口或者抽象类实现. 具体策略角色:包装了 ...

  10. 【转载】Lua中实现类的原理

    原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...