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?
需要用线性的时间解出问题,所以不能使用暴力的算法进行逐个比较。
import java.util.LinkedList;
class num239 {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums.length == 0) return new int[0];
int[] res = new int[nums.length-k+1];
LinkedList<Integer> queue = new LinkedList<Integer>();
for(int i=0; i<nums.length; i++){
while(!queue.isEmpty() && queue.peek() == i-k) queue.poll();
while(!queue.isEmpty() && nums[queue.peekLast()] < nums[i]) queue.removeLast();
queue.add(i);
if(i >= k-1) res[i-k+1] = nums[queue.peek()];
}
return res;
}
public static void main(String[] args) {
int[] nums = {1,3,-1,-3,5,3,6,7};
int k = 3;
num239 solution = new num239();
int[] res = solution.maxSlidingWindow(nums, k);
for(int item:res){
System.out.println(item);
}
}
}
使用一个双向队列保存当前窗口中的最大值的下标,当队首元素等于i-k时,表示窗口右移,不需要进行比较,则移除队首元素。否则比较将要进来的元素和队尾的值,如果队尾元素比将要进来的元素小的话则移除,然后将当前元素入队列,队首总是保存当前窗口中的最大值,每次获取队首的值放入结果数组中。
1,3,-1,-3,5,3,6,7 k=3
队列 i=0,queue =[ 0 ]; i = 1, queue 移除0,queue =[ 1 ] ; i=2, queue = [ 1,2] , res = [3];
i=3, queue = [ 1, 2, 3], res = [3,3]; i=4, queue = [2,3], queue = [4], res = [3,3,5];
i=5, queue = [4, 5], res = [3,3,5,5]; i=6, queue = [6], res= [3,3,5,5,6];
i=7, queue = [7], res= [3,3,5,5,6,7];