码迷,mamicode.com
首页 > Windows程序 > 详细

[Leetcode] Sliding Window Maximum

时间:2015-09-01 21:18:44      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:

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].

刚开始想到是使用heap来保存当前遍历过的元素,并且保持最大堆状态,每当达到从堆中取出一个元素,则将当前节点之前的第k个元素从堆中删除,这样堆一直保持k的大小,整体算法的复杂度是O(N*k(logk)),从堆中删除需要找到需要找到节点,时间是O(K),删除O(Log(k)),最多N个节点。

 1     private int[] method2(int []nums,int k){
 2         if(nums.length==0) return nums;
 3         Comparator<Integer> compare = new Comparator<Integer>(){
 4             public int compare(Integer i1,Integer i2){
 5                 return i2-i1;
 6             }
 7         };
 8         PriorityQueue<Integer> heap = new PriorityQueue<Integer>(compare);
 9         int [] res = new int[nums.length-k+1];
10         for(int i=0;i<nums.length;i++){
11             heap.offer(nums[i]);
12             if(i>=(k-1)){
13                 res[i-k+1] = heap.peek();
14                 heap.remove(nums[i-k+1]);
15             }
16         }
17         return res;
18     }
19     public int[] maxSlidingWindow(int[] nums, int k) {
20         return method2(nums,k);
21     }

后来发现使用双端队列,就可以,并且时间复杂度降低到了O(N)

 1     private int[] method1(int[] nums, int k){
 2         if(nums.length==0) return nums;
 3         LinkedList<Integer> dequeue = new LinkedList<Integer>();
 4         int [] res = new int[nums.length-k+1];
 5         for(int i=0;i<nums.length;i++){
 6             int data = nums[i];
 7             //当data等于双端队列当中的最大值的时候,不能讲队列中的元素弹出,
 8             //原因是这个元素可能会被后面的某个元素视为最大元素,当前遇到的这个值虽然和双端队列当中目前的最大值是相等的,但是他出现的比较晚,在后面的窗口当中他可能会被用到。
 9             //举个例子 4444333,如果遇到想的就删除,那么
10             //4 4 4 4 变为空,遇到3的时候虽然窗口大小为3的窗口中的最大值是4,但是4已经不存在了,关键是在前面已经把他删除了。
11             
12             while(dequeue.size()!=0&&data>dequeue.getFirst()) dequeue.removeFirst();
13             dequeue.addFirst(data);
14             if(i>=k-1){
15                 int largest = dequeue.getLast();
16                 res[i-k+1] = largest;
17                 if(largest==nums[i-k+1]){
18                     dequeue.removeLast();
19                 }
20             }
21         }
22         return res;
23     }

这里的关键问题是while循环当中为甚me在当前data比队列中的第一个元素相等的时候,会保留相等元素,详细原因看参考代码中的注释。

 

[Leetcode] Sliding Window Maximum

标签:

原文地址:http://www.cnblogs.com/deepblueme/p/4776789.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!