由于长时间不刷题,总会忘记一些题目解法,就当作记录思路的地方吧。
题目描述如下:
public class MaxSlidingWindow_239 {
/**
* 可以采用单调队列的方式,将数据入队列,如果数据大于已入队列的数据,就将其他数据移出队列。
* 例如数组如下:
* 2 1 5 2 3 1
*
* -------------------
* 2 1 <-5
* -------------------
* 当5进入单独队列时,由于1和2小于5,就将其退出队列,
* 注意这里的比较是从已经入队数据的右边比起,先比1,再比2。
* 结果如下
* -------------------
* 5
* -------------------
*
*
* 当3入时,由于当前3比2大,会把2也出队。
* 注意:这里一样也是先比队列中右边的数字,如果先比左边的,会因为5大于3而停止遍历。
* -------------------
* 5 2 <-3
* -------------------
* 此时剩下5和3
* -------------------
* 5 3
* -------------------
*
*
*/
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
Deque<Integer> deque = new LinkedList<>();
/**
* Deque其实就是双端队列
* --------------------------------
* pollFirst <- <- offerLast
* 该方向数据出队列 -------------------------------- 该方向数据进队列
*
* --------------------------------
* offerFirst -> -> pollLast
* 该方向数据入队列 -------------------------------- 该方向数据出队列
*
* ↑ ↑
* 队列头部 队列尾部
*
* offerLast和pollFirst是一组先进先出的操作
* deque.addLast(1);
* deque.addLast(2);
* 在队列中中就是 [1,2]
* deque.pollFirst()会取出1
* 再deque.pollFirst()会取出2
*
*/
//先将前k个进行处理
for (int i = 0; i < k; i++) {
//查看队列不为空,并且当前元素大于等于队列尾部元素,注意由于后续还要判断该数字是否要从队列头退出,这里采用队列中直接记录下标的方式,方便后续操作
while (!deque.isEmpty() && nums[i] >= nums[deque.peekFirst()]){
//就把队尾元素退出队列
deque.pollFirst();
}
//将当前元素放入队列中
deque.offerLast(i);
}
/**
* 最终返回的结果是 n - k + 1个窗口
* 例如数组[1,3,-1,-3,5,3,6,7], k = 3, n1=8
* 最终的结果是[3,3,5,5,6,7] n2=6
* 那么 n2 = n1 - k + 1
*/
int[] result = new int[n-k+1];
//将上面已经处理的k个的结果,也就是将队列头,即最大值,放入result中
result[0] = nums[deque.peekFirst()];
//对剩余的 n - k 个进行处理
for (int i = k; i < n; i++) {
//将当前数字与队列中队尾的数字进行比较
while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
//当前数字大于队尾就将队尾数字退出队列
deque.pollLast();
}
//将当前数字加入队列
deque.offerLast(i);
//判断下队列头部所插入元素的下标是否已经超出了当前的窗口
while (deque.peekFirst() <= i - k) {
//超出窗口就将该元素重队列头退出。
deque.pollFirst();
}
//将当前窗口内的队列头元素,即最大值的放入result结果数组
result[i - k + 1] = nums[deque.peekFirst()];
}
return result;
}
public static void main(String[] args) {
MaxSlidingWindow_239 test = new MaxSlidingWindow_239();
int[] nums = new int[]{1,3,-1,-3,5,3,6,7};
int k = 3;
int[] result = test.maxSlidingWindow(nums, k);
for (int i = 0; i < result.length; i++) {
System.out.print(result[i]+" ");
}
System.out.println();
nums = new int[]{1, -1};
k = 1;
result = test.maxSlidingWindow(nums, k);
for (int i = 0; i < result.length; i++) {
System.out.print(result[i]+" ");
}
System.out.println();
nums = new int[]{7, 2, 4};
k = 2;
result = test.maxSlidingWindow(nums, k);
for (int i = 0; i < result.length; i++) {
System.out.print(result[i]+" ");
}
}
}