[Leetcode] Sliding Window Maximum
2015-09-01 20:25
465 查看
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 =
Therefore, return the max sliding window as
刚开始想到是使用heap来保存当前遍历过的元素,并且保持最大堆状态,每当达到从堆中取出一个元素,则将当前节点之前的第k个元素从堆中删除,这样堆一直保持k的大小,整体算法的复杂度是O(N*k(logk)),从堆中删除需要找到需要找到节点,时间是O(K),删除O(Log(k)),最多N个节点。
后来发现使用双端队列,就可以,并且时间复杂度降低到了O(N)
这里的关键问题是while循环当中为甚me在当前data比队列中的第一个元素相等的时候,会保留相等元素,详细原因看参考代码中的注释。
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].
刚开始想到是使用heap来保存当前遍历过的元素,并且保持最大堆状态,每当达到从堆中取出一个元素,则将当前节点之前的第k个元素从堆中删除,这样堆一直保持k的大小,整体算法的复杂度是O(N*k(logk)),从堆中删除需要找到需要找到节点,时间是O(K),删除O(Log(k)),最多N个节点。
private int[] method2(int []nums,int k){ if(nums.length==0) return nums; //递减排序方式 Comparator<Integer> compare = new Comparator<Integer>(){ public int compare(Integer i1,Integer i2){ return i2-i1; } }; PriorityQueue<Integer> heap = new PriorityQueue<Integer>(compare); int [] res = new int[nums.length-k+1]; for(int i=0;i<nums.length;i++){ heap.offer(nums[i]); if(i>=(k-1)){ res[i-k+1] = heap.peek(); heap.remove(nums[i-k+1]); } } return res; } public int[] maxSlidingWindow(int[] nums, int k) { return method2(nums,k); }
后来发现使用双端队列,就可以,并且时间复杂度降低到了O(N)
private int[] method1(int[] nums, int k){ if(nums.length==0) return nums; LinkedList<Integer> dequeue = new LinkedList<Integer>(); int [] res = new int[nums.length-k+1]; for(int i=0;i<nums.length;i++){ int data = nums[i]; //当data等于双端队列当中的最大值的时候,不能讲队列中的元素弹出, //原因是这个元素可能会被后面的某个元素视为最大元素,当前遇到的这个值虽然和双端队列当中目前的最大值是相等的,但是他出现的比较晚,在后面的窗口当中他可能会被用到。 //举个例子 4444333,如果遇到想的就删除,那么 //4 4 4 4 变为空,遇到3的时候虽然窗口大小为3的窗口中的最大值是4,但是4已经不存在了,关键是在前面已经把他删除了。 while(dequeue.size()!=0&&data>dequeue.getFirst()) dequeue.removeFirst(); dequeue.addFirst(data); if(i>=k-1){ int largest = dequeue.getLast(); res[i-k+1] = largest; if(largest==nums[i-k+1]){ dequeue.removeLast(); } } } return res; }
这里的关键问题是while循环当中为甚me在当前data比队列中的第一个元素相等的时候,会保留相等元素,详细原因看参考代码中的注释。
相关文章推荐
- JavaWeb图片上传随谈(一)
- linux下文件夹的创建、复制、剪切、重命名、清空和删除命令
- 012-01Spark On YARN 环境搭建
- Linux命令学习篇0——原产地
- 表单提交中get和post方式的区别
- 【JavaSE】day12_异常(Exception)
- hive和mysql关联相对应表详情
- 轻松python之文件专题-读取文件专题
- Magento collection filtering 嵌套where条件的简单写法
- Windows 10 : 使用BCDboot恢复双系统启动
- javascript 闭包学习
- sqlplus登录Oracle时ORA-01017: invalid username/password; logon denied的错误
- 轻松python之文件专题-读取文件专题
- 博客第一篇
- ostream 保存数据出现乱码原因之一
- 给定100亿个网址,如何检测出重复的文件。
- DP 水题 HDU1003
- 文章标题
- 深入理解Java对象序列化
- iOS调试——基础(二)