题目描述:

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. Java资源大全中文版(Awesome最新版)

    Awesome系列的Java资源整理.awesome-java 就是akullpp发起维护的Java资源列表,内容包括:构建工具.数据库.框架.模板.安全.代码分析.日志.第三方库.书籍.Java 站 ...

  2. web api添加拦截器

    实现思路 1.标识控制器有拦截特性: 2.控制器拦截处理: 代码实现 1.标识控制器有拦截特性,代码: [MyFilter] public string PostFindUser([FromBody] ...

  3. C# 给Word文档添加内容控件

    C# 给Word文档添加内容控件 在MS Word中,我们可以通过内容控件来向word文档中插入预先定义好的模块,指定模块的内容格式(如图片.日期.列表或格式化的文本等),从而创建一个结构化的word ...

  4. c 数组与指针的使用注意事项

    数组变量和指针变量有一点小小的区别 所以把数组指针赋值给指针变量的时候千万要小心 加入把数组赋值给指针变量,指针变量只会包含数组的地址信息 而对数组的长度一无所知 相当于指针丢失了一部分信息,我们把这 ...

  5. 读书笔记--SQL必知必会07--创建计算字段

    7.1 计算字段 字段(field),基本与列(column)含义相同. 利用计算字段可以直接从数据库中检索出转换.计算或格式化过的数据. 计算字段不实际存在于数据库表中,是运行时在SELECT语句内 ...

  6. 【分布式】Zookeeper系统模型

    一.前言 前面已经讲解了Zookeeper的一些应用场景,但是并没有深入到Zookeeper内部进行分析,本篇将讲解其系统模型. 二.系统模型 2.1 数据模型 Zookeeper的数据节点称为ZNo ...

  7. 11.JAVA之GUI编程菜单

    功能:添加菜单组件 知识总结: 代码如下: import java.awt.FlowLayout; import java.awt.Frame; import java.awt.Menu; impor ...

  8. git 出错误“值对于Uint32太大或太小”

    提交git代码的时候报的错误 这是因为修改的东西太少的原因,应该多修改一些就可以提交了 例如:只是删除了一个空格或者一个字符就提交git代码的话就会提示这个错误 解决方法:多多的改变一下代码,比如增加 ...

  9. java基础知识 多线程

    package org.base.practise9; import org.junit.Test; import java.awt.event.WindowAdapter; import java. ...

  10. Is-A,Has-A,Use-A(转载)

    原文地址:http://blog.csdn.net/loveyou128144/article/details/4749576 而Is-A,Has-A,Use-A则是用来描述类与类之间关系的.简单的说 ...