​welcome to my blog​

LeetCode Top 100 Liked Questions 239. Sliding Window Maximum (Java版; Hard)

题目描述

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?
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
int[] res = new int[n-k+1];
int p = 0;
LinkedList<Integer> queue = new LinkedList<>();
for(int i=0; i<n; i++){
while(!queue.isEmpty() && nums[i] > nums[queue.peekLast()]){
queue.pollLast();
}
queue.add(i);
if(i-queue.peek()>=k){
queue.poll();
}
if(i+1>=k){
res[p++] = nums[queue.peek()];
}
}
return res;
}
}

第一次做; 队列中存储的是元素的索引, 因为索引含有更多的信息, 既可以找到元素值, 又能和滑窗的边界进行比较从而确定队首元素是否还在滑窗内;滑窗的左右边界: 右边界就是i, 左边界是i-k+1

import java.util.LinkedList;

class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
//
if(nums==null||nums.length==0)
return new int[]{};
//一共有n-k+1个滑动窗口
int[] res = new int[nums.length-k+1];
//数组中每个元素都入队一次, 如果入队的元素比队尾元素大与等于,就先弹出队尾元素,直到队尾元素大于入队元素
//或者队列为空,此时再压入当前待入队元素
//细节:实际操作中,队列存储的是索引; 因为位置信息更有价值,既可以找到nums中的元素,又能判断当前的框是否过期
LinkedList<Integer> queue = new LinkedList<>();
for(int i=0; i<nums.length; i++){
while(!queue.isEmpty() && nums[i] >= nums[queue.getLast()]){
queue.pollLast();
}
//当前元素索引进队
queue.add(i);
//如果队列首元素小于滑窗的左边界, 需要弹出队首元素
if(queue.getFirst() < i-k+1)
queue.poll();
//i==k-1时出现了第一个框, 记录该滑窗中的最大值
if(i>=k-1){
res[i-k+1] = nums[queue.getFirst()];
}
}
return res;
}
}