剑指 Offer 59 - I. 滑动窗口的最大值
题目描述
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。
解答
class Solution {
/**
采用大顶堆的数据结构:
定义一个大顶堆,当滑动窗口向右移动时,将新包含的元素插入到大顶堆中;
然后读取堆顶元素即为当前滑动窗口中的最大值,如果堆顶元素不在滑动窗口范围内,
那么他一定在滑动窗口左边界的左边,以后随着滑动窗口右移,他也肯定不会出现在滑动窗口范围中,
所以可以将其从大顶堆中移除,直到遇到堆顶元素在滑动窗口范围内,则为滑动窗口范围内真正的最大值
为了便于判断是否在范围内,可以在大顶堆中存储位置+值的数组
*/
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length == 0){
return new int[0];
}
int[] res = new int[nums.length-k+1];
//定义大顶堆
PriorityQueue<int[]> bigHeap = new PriorityQueue<>(new Comparator<int[]>(){
public int compare(int[] o1,int[] o2){ //第一个入参是靠后面的数,第二个入参是靠前面的数
if(o2[1] >= o1[1]){
return 1; //返回正数代表位置不用调整
}else{
return -1; //返回负数代表位置需要调整
}
}
});
//先把前k个放到大顶堆中
for(int i = 0;i < k;i++){
bigHeap.offer(new int[]{i,nums[i]});
}
res[0] = bigHeap.peek()[1];
int j =1;
int i = k;
while(i < nums.length){
bigHeap.offer(new int[]{i,nums[i]});
while(bigHeap.peek()[0] < (i-k+1)){
bigHeap.poll();
}
res[j++] = bigHeap.peek()[1];
i++;
}
return res;
}
}