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 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的更多相关文章
- [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 ...
- [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 ...
- leetcode 239 Sliding Window Maximum
这题是典型的堆排序算法,只是比一般的堆算法多了删除的操作,有两件事需要做: 1 用一个hash表存储从输入数组索引到堆数组(用于实现堆的那个数组)所以的映射,以便在需要删除一个元素的时候能迅速定位到堆 ...
- [leetcode] #239 Sliding Window Maximum (Hard)
原题链接 题意: 给定一个数组数字,有一个大小为k的滑动窗口,它从数组的最左边移动到最右边.你只能在窗口看到k个数字.每次滑动窗口向右移动一个位置. 记录每一次窗口内的最大值,返回记录的值. 思路: ...
- leetcode面试准备:Sliding Window Maximum
leetcode面试准备:Sliding Window Maximum 1 题目 Given an array nums, there is a sliding window of size k wh ...
- 【LeetCode】239. Sliding Window Maximum
Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving fr ...
- 【刷题-LeetCode】239. Sliding Window Maximum
Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving from ...
- [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 ...
- Leetcode: sliding window maximum
August 7, 2015 周日玩这个算法, 看到Javascript Array模拟Deque, 非常喜欢, 想用C#数组也模拟; 看有什么新的经历. 试了四五种方法, 花时间研究C# Sorte ...
随机推荐
- java发送http的get、post请求
转载博客:http://www.cnblogs.com/zhuawang/archive/2012/12/08/2809380.html Http请求类 package wzh.Http; impor ...
- 细说Promise
一.前言 JavaScript是单线程的,固,一次只能执行一个任务,当有一个任务耗时很长时,后面的任务就必须等待.那么,有什么办法,可以解决这类问题呢?(抛开WebWorker不谈),那就是让代码异步 ...
- 从零开始编写自己的C#框架(1)——前言
记得十五年前自学编程时,拿着C语言厚厚的书,想要上机都不知道要用什么编译器来执行书中的例子.十二年前在大学自学ASP时,由于身边没有一位同学和朋友学习这种语言,也只能整天混在图收馆里拼命的啃书.而再后 ...
- 基於tiny4412的Linux內核移植--- 中斷和GPIO學習(1)
作者 彭東林 pengdonglin137@163.com 平臺 tiny4412 ADK Linux-4.4.4 u-boot使用的U-Boot 2010.12,是友善自帶的,爲支持設備樹和uIma ...
- 学习SpringMVC——国际化+上传+下载
每个星期一道菜,这个星期也不例外~~~ 一个软件,一个产品,都是一点点开发并完善起来的,功能越来越多,性能越来越强,用户体验越来越好……这每个指标的提高都需要切切实实的做点东西出来,好比,你的这个产品 ...
- ionic之$ionicGesture手势(大坑)
鄙人来本公司前未用过ionic框架,但由于ionic是基于angularjs封装的,正好我用过angularjs,很荣幸的面试就过了,然后通过该网站http://www.ionic.wang(后面简称 ...
- C#7.0中有哪些新特性?
以下将是 C# 7.0 中所有计划的语言特性的描述.随着 Visual Studio “15” Preview 4 版本的发布,这些特性中的大部分将活跃起来.现在是时候来展示这些特性,你也告诉借此告诉 ...
- 数据库进阶之路(五) - MySQL行锁深入研究
由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图书借阅系统:假设id=1的这本书库存为1,但是有2个人同时来借这本书,此处的逻辑为: ; --如果restnum大于0,执行u ...
- mvc 重定向的几种方式
在RouteConfig添加一个简单的路由 //新增路由 routes.MapRoute( name: "Article", url: "Detial/{id}" ...
- 【夯实PHP基础】php开发时遇到白页的调试方法
本文地址 分享提纲: 1. 设置报错报错级别,显示报错 2. 白页的可能原因 1.[设置报错报错级别,显示报错] php开发时,访问地址也对,但就是不出来页面,显示的是 白的页面,所以就可 ...