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 }