双端队列
class Solution {
//利用双端队列
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque = new LinkedList<>();
int n = nums.length;
int[] res = new int[n-k+1];
for(int i=0 ; i<k ; ++i){
while(!deque.isEmpty() && nums[i]>nums[deque.peekFirst()]){
deque.removeFirst();
}
deque.offerFirst(i);//栈顶
}
res[0] = nums[deque.peekLast()]; //队尾元素为当前窗口最大值
//队列保证了元素进入的先后顺序,那么就可以保证队尾的元素下标是从小到大的
for(int i=k ; i<n ; ++i){
while(!deque.isEmpty() && deque.peekLast() <= i-k){
deque.removeLast();//超出滑动窗口下表的元素出队
}
while(!deque.isEmpty() && nums[i] > nums[deque.peekFirst()]){
deque.removeFirst();
}
deque.offerFirst(i);
res[i-k+1] = nums[deque.peekLast()];
}
return res;
}
}
优先队列:
class Solution {
//优先队列
public int[] maxSlidingWindow(int[] nums, int k) {
PriorityQueue<int[]> pq = new PriorityQueue<>(new Comparator<int[]>(){ //默认小顶堆
public int compare(int[] pair1, int[] pair2){
return pair1[0] == pair2[0]?pair2[1]-pair1[1]:pair2[0]-pair1[0]; //元素相等二点情况下,下表更大的优先排在更前面(相对也更大些)
}
});
int n = nums.length;
int[] res = new int[n-k+1];
for(int i=0 ; i<k ; ++i){
pq.offer(new int[]{nums[i], i});
}
res[0] = pq.peek()[0];
for(int i=k ; i<n ; ++i){
pq.offer(new int[]{nums[i], i});
while(pq.peek()[1] <= i-k){
pq.poll();
}
res[i-k+1] = pq.peek()[0];
}
return res;
}
}