题目描述:

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.

For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.

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

Therefore, return the max sliding window as [3,3,5,5,6,7].

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

分析:

  开始觉得题目的形式很眼熟,感觉应该用Max Heap解。但是显然Max Heap的复杂度是O(n*logK),事实上应该用类似与插入排序的手法,利用双向队列求解。遍历数组,每遇到一个数就与队列的末尾进行比较,若队列末尾的数小于当前数,则队列末尾退出队列,如此往复,知道队列为空,或者队列里的数都大于当前数,最后插入当前数。由此可知,队列中的数是按照从队首到队尾从大到小排序而成。我们每次将窗口往前移动一格,就插入一个数,并且在队首取得窗口的最大值。不过,这里需要注意一点,队首的数可能已经位于窗口之外了!因此,我们用了一个比较tricky的手法,那就是在队列中插入的并不是具体元素的值,而是元素在数组中的位置,这样我们在遍历数组的过程中就能判断队列中的数是否仍然在队列中了。若我们在取最大值时,发现队首的元素已经在窗口之外了,则将其弹出,直到找到仍在窗口内的队首元素为止。最后,不断循环上述过程,即可得到问题的解。

  但是,问题是为什么上面说的解法是O(n)的复杂度呢,插入排序的思想和上面说的是完全一致的,可是复杂度却是O(n*n)。其实我们可以发现,上述解法与插入排序不同的是,不存在重复比较。在插入新元素时,比新元素小的元素都退出队列了,因为它们不可能是之后窗口的解。在取最大值时,所有不再窗口内的元素也全都弹出队列了。最终我们可以发现,每次比较都伴随着插入或者删除元素,而元素个数为n,因此全局的操作最多可能分别只有n次的插入,删除,比较操作,所以复杂度为O(n)。(第一次用双向队列求解问题,感觉还是挺神奇的)

代码:

class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> d;
vector<int> ans;
if(nums.size()==0) {
return ans;
}
d.push_front(0);
for(int i=1;i<k;i++) {
while(!d.empty()&&nums[d.back()]<nums[i]) {
d.pop_back();
}
d.push_back(i);
}
ans.push_back(nums[d.front()]);
for(int i=k;i<nums.size();i++) {
while(!d.empty()&&nums[d.back()]<nums[i]) {
d.pop_back();
}
d.push_back(i);
while(d.front()<=i-k) {
d.pop_front();
}
ans.push_back(nums[d.front()]);
} return ans;
}
};

  

LeetCode题解-----Sliding Window Maximum的更多相关文章

  1. [LeetCode] 239. 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 ...

  2. [leetcode]239. 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 ...

  3. leetcode 239 Sliding Window Maximum

    这题是典型的堆排序算法,只是比一般的堆算法多了删除的操作,有两件事需要做: 1 用一个hash表存储从输入数组索引到堆数组(用于实现堆的那个数组)所以的映射,以便在需要删除一个元素的时候能迅速定位到堆 ...

  4. [leetcode] #239 Sliding Window Maximum (Hard)

    原题链接 题意: 给定一个数组数字,有一个大小为k的滑动窗口,它从数组的最左边移动到最右边.你只能在窗口看到k个数字.每次滑动窗口向右移动一个位置. 记录每一次窗口内的最大值,返回记录的值. 思路: ...

  5. leetcode面试准备:Sliding Window Maximum

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

  6. 【LeetCode】239. Sliding Window Maximum

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

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

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

  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 the a ...

  9. Leetcode: sliding window maximum

    August 7, 2015 周日玩这个算法, 看到Javascript Array模拟Deque, 非常喜欢, 想用C#数组也模拟; 看有什么新的经历. 试了四五种方法, 花时间研究C# Sorte ...

随机推荐

  1. Android之常见问题集锦Ⅰ

     Android中如何在ViewPager中使动态创建的ImageView铺满屏幕 最近在做东西的时候,有一个要求,就是把用于在ViewPager里面轮播的图片铺满屏幕,但是中间遇到的问题是,Imag ...

  2. 【NLP】大数据之行,始于足下:谈谈语料库知多少

    大数据之行,始于足下:谈谈语料库知多少 作者:白宁超 2016年7月20日13:47:51 摘要:大数据发展的基石就是数据量的指数增加,无论是数据挖掘.文本处理.自然语言处理还是机器模型的构建,大多都 ...

  3. 设计模式--观察者模式初探和java Observable模式

    初步认识观察者模式 观察者模式又称为发布/订阅(Publish/Subscribe)模式,因此我们可以用报纸期刊的订阅来形象的说明: 报社方负责出版报纸. 你订阅了该报社的报纸,那么只要报社发布了新报 ...

  4. ASP.NET Core 中文文档 第二章 指南(4.2)添加 Controller

    原文:Adding a controller 翻译:娄宇(Lyrics) 校对:刘怡(AlexLEWIS).何镇汐.夏申斌.孟帅洋(书缘) Model-View-Controller (MVC) 架构 ...

  5. C# 一段绘图代码 在form_load事件不能显示图

    今天无意将一段绘图代码 写在form_load事件了,结果不能显示绘图.(代码:Graphics g = this.CreateGraphics();Pen pen = new Pen(Color.R ...

  6. javascript性能优化:创建javascript无阻塞脚本

    javaScript 在浏览器中的运行性能,在web2.0时代显得尤为重要,成千上万行javaScript代码无疑会成为性能杀手, 在较低版本的浏览器执行JavaScript代码的时候,由于浏览器只使 ...

  7. MySQL: Table 'mysql.plugin' doesn't exist的解决

    安装解压版MySQL以后,不能启动,日志里面出现了这个错误: MySQL: Table 'mysql.plugin' doesn't exist 这是因为mysql服务启动时候找不到内置数据库&quo ...

  8. 如何解决例如i++的线程不安全性

    AtomicBoolean.AtomicInteger.AtomicLong.AtomicReference 各种原子性关键字,可以解决比如i++的线程不安全性的因素

  9. gRPC源码分析0-导读

    gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...

  10. LogBack简易教程

    1.简介 LogBack是一个日志框架,它与Log4j可以说是同出一源,都出自Ceki Gülcü之手.(log4j的原型是早前由Ceki Gülcü贡献给Apache基金会的) 1.1 LogBac ...