from : https://leetcode.com/problems/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]
.
思路一:
优先队列,时间复杂度O(nk)。
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(k <= 0) {
return new int[]{};
}
PriorityQueue<Integer> heap = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
return b-a;
}
});
int n = nums.length-k+1;
int[] maxes = new int[n];
for(int i=0, k_1=k-1; i<k_1; ++i) {
heap.add(nums[i]);
}
for(int i=0; i<n; ++i) {
heap.add(nums[k+i-1]);
maxes[i] = heap.peek();
heap.remove(nums[i]);
}
return maxes;
}
}
思路二:
用双向队列记录不增的小标。
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if(k <= 0 || null == nums) return new int[]{};
int k1 = k-1;
int[] maxes = new int[nums.length-k+1];
LinkedList<Integer> idxes = new LinkedList<Integer>();
for(int i=0, len=nums.length; i<len; ++i) {
int n = nums[i];
while(!idxes.isEmpty() && nums[idxes.getLast()] < n) {
idxes.removeLast();
}
idxes.add(i);
if(i>=k1) {
maxes[i-k1] = nums[idxes.getFirst()];
}
if(idxes.getFirst()+k-1 == i) {
idxes.removeFirst();
}
}
return maxes;
}
}