LeetCode(239)-Sliding Window Maximum/返回滑动窗口最大值(双端队列)

题目:

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?

翻译:

给定一个数组编号,有一个大小为k的滑动窗口,它从数组的最左边移动到最右边。你只能在窗口看到k个数字。每次滑动窗口右移一个位置。返回最大滑动窗口。

思路:

题目是将长度为k的滑动窗口从最左滑到最右,分别找到每个窗口下的最大值。
此题主要在于处理滑动过程中的中值变化。
如果想要在线程时间复杂度解决问题,那么就得动态更新当前窗口的最大值。
由于数组的无序性,滑动过程最大值的变化是不确定的,因此使用单调队列 解决问题。

  • 单调队列:在队尾添加元素,在队首删除元素,时刻维护队列中的最大值,使其查询时间为O(1)。
    我们使用双端队列实现在两端插入和删除操作。
    队首元素始终是当前窗口最大值的索引,并且队列长度始终<=k
  1. 对于将插入队列的元素k,我们将其与队列中的元素进行比较,前面比k小的,直接移出队列(因为不会再成为后面滑动窗口的最大值)。
  2. 队首比k大的值,比较两者下标,如果队首元素已经不再窗口内,那么移出队列。队列中第一次元素是当前窗口的最大值。

代码实现:

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums==null||nums.length==0)
            return new int[0];
            
        int[] res=new int[nums.length+1-k];
        int index=0;
        //双端队列
        Deque<Integer> dq=new LinkedList();
        for(int i=0;i<nums.length;i++){
            //i为窗口右端,begin为窗口左端。
            int begin=i-k+1;
            //判断队首元素是否过期,也就是其已不再窗口范围内
            while(!dq.isEmpty()&&dq.peekFirst()<begin)
                dq.pollFirst();
            //队列是需要保持递减的,因为要保证队首是窗口的最大元素
            //比它小的元素也不必再次入队,因为i是最新的,也是最大的
            //当它失效时,当前队列的元素肯定已经全部失效。    
            while(!dq.isEmpty()&&nums[dq.peekLast()]<=nums[i])
                dq.pollLast();
            //将当前角标压入队列    
            dq.add(i);
            //最开始k-1个begin肯定是小于0的
            if(begin>=0){
                res[begin]=nums[dq.peekFirst()];
            }
        }
        return res;
    }
} 

你可能感兴趣的:(LeetCode(239)-Sliding Window Maximum/返回滑动窗口最大值(双端队列))