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. CodeForces - 158B.Taxi (贪心)

    CodeForces - 158B.Taxi (贪心) 题意分析 首先对1234的个数分别统计,4人组的直接加上即可.然后让1和3成对处理,只有2种情况,第一种是1多,就让剩下的1和2组队处理,另外一 ...

  2. Redux的应该注意的问题

    1. Store中的State修改不能直接修改原有的State,若直接修改State,则redux中的所有操作都将指向 内存中的同一个state,将无法获取每一次操作前后的state,就无法追溯sta ...

  3. Delight for a Cat

    Time Limit: 1000 ms Memory Limit: 512 MB Description ​ 从前,有一只懒猫叫CJB.每个小时,这只猫要么在睡觉,要么在吃东西,但不能一边睡觉一边吃东 ...

  4. JavaScript去除空格trim()的原生实现

    W3C那帮人的脑袋被驴踢了,直到javascript1.8.1才支持trim函数(与trimLeft,trimRight),可惜现在只有firefox3.5支持.由于去除字符串两边的空白实在太常用,各 ...

  5. C++之tinyXML的使用详解

    tinyXML一款很优秀的操作C++类库,文件不大,但方法很丰富,和apache的Dom4j可以披靡啊!习惯了使用java类库的我看到这么丰富的c++类库,很高兴!它使用很简单,只需要拷贝几个文件到你 ...

  6. 微服务学习三:springboot与springcloud集成之Eurake的使用(server端,client端)

    这个多亏了网站上的一个大神的博客: http://blog.csdn.net/forezp/article/details/70148833 强烈推荐学习: 1.springcloud是什么,这个大家 ...

  7. mybatis的mapper的特殊符号处理

    这种问题在xml处理sql的程序中经常需要我们来进行特殊处理. 其实很简单,我们只需作如下替换即可避免上述的错误: < <= > >= & ' " < ...

  8. 使用 Rational AppScan 保证 Web 应用的安全性,第 1 部分: Web 安全与 Rational AppScan 入门

    前言 当今世界,Internet(因特网)已经成为一个非常重要的基础平台,很多企业都将应用架设在该平台上,为客户提供更为方便.快捷的服务支持.这些应用 在功能和性能上,都在不断的完善和提高,然而在非常 ...

  9. C# 中的委托和事件(详解)

    C# 中的委托和事件 委托和事件在 .NET Framework 中的应用非常广泛,然而,较好地理解委托和事件对很多接触 C# 时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太 ...

  10. 51Nod 1009 数字1的个数 | 数位DP

    题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9 ...