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 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. Return the max sliding window.

Example:

Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
Output: [3,3,5,5,6,7] 
Explanation: 

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

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

Follow up:
Could you solve it in linear time?

注意:一定要对的参数进行合法性验证

使用大顶堆完成,时间复杂度O(nlogk)

 1 public int[] maxSlidingWindow(int[] nums, int k) {//大顶堆 my
 2         if(nums.length<k||k==0){//一定要合法性验证
 3             return new int[0];
 4         }
 5         int[] re= new int[nums.length-k+1];
 6         
 7         PriorityQueue<Integer> heap = new PriorityQueue<Integer>(k,new Comparator<Integer>() {//java 优先队列默认是小顶堆
 8             @Override
 9             public int compare(Integer o1, Integer o2) {
10                 return o2-o1;
11             }
12         });
13         for (int i = 0; i < k; i++) {
14             heap.add(nums[i]);
15         }
16         re[0]=heap.peek();
17         for (int i = 0; i < nums.length-k; i++) {
18             heap.remove(Integer.valueOf(nums[i]));
19             heap.add(nums[i+k]);
20             re[i+1]=heap.peek();
21         }
22         return re;
23     }

注意:堆保留了top个数,但是该题只需要保留最大的,故有O(n)的算法:

 1 public int[] maxSlidingWindow(int[] nums, int k) {//双端队列 mytip
 2         if(nums.length<k||k<=0){
 3             return new int[0];
 4         }
 5         int[] re= new int[nums.length-k+1];
 6         Deque<Integer> deque = new LinkedList<>();//队列中保留的位索引
 7         for (int i = 0; i < nums.length; i++) {
 8             if(0<deque.size()&&deque.getFirst()<=i-k){//删除窗口划过的值  
 9                 deque.pollFirst();
10             }
11             while(0<deque.size()&&nums[deque.getLast()]<nums[i]){//删除比当前值小的值
12                 deque.pollLast();
13             }
14             deque.add(i);
15             if(i>=(k-1)){
16                 re[i-k+1]=nums[deque.getFirst()];
17             }
18         }
19         return re;
20     }

猜你喜欢

转载自www.cnblogs.com/zhacai/p/10567783.html