Leetcode 239 Sliding Window Maximum (指定滑动窗最大值) (滑动窗口)


Leetcode

问题描述

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

解题方法

  首先生成双端队列deque, deque用于存放数组nums的下标。

  1. 如果deque为空,直接把下标i放deque,放入过程结束;
  2. 如果deque不为空,取出当前deque队尾存放的下表,假设为j;
    1). 如果nums[j]>nums[i], 直接把下标i放入队尾,放入过程结束;
    2). 如果nums[j]<=nums[i],把j从deque中弹出,继续deque的放入规则;
  3. 如果deque队头的下标等于i-w,说明当前deque队头的下标已过期,弹出当前队头的下标。
** Solution Java (deque) **
** 8ms, beats 87.35% **
**49.5, beats 6.25% **
public class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums == null || nums.length < k || k < 1)
            return new int[0];
        Deque<Integer> deque = new ArrayDeque<>();
        int index = 0;
        int[] ans = new int[nums.length + 1 - k];
        for (int i = 0; i < nums.length; ++i) {
            while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i])
                deque.pollLast();
            deque.offer(i);
            if (deque.peek() == i - k)
                deque.poll();
            if (i >= k - 1)
                ans[index++] = nums[deque.peek()];
        }
        return ans;
    }
}
** Solution Java LinkedList **
** 6ms, beats 90.50% **
** 47.8MB, beats 6.25% **
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums == null || k<1 || nums.length < k)
            return new int[0];
        LinkedList<Integer> list = new LinkedList<>();
        int[] ans = new int[nums.length - k + 1];
        int index = 0;
        for (int i = 0; i < nums.length; ++i) {
            while (!list.isEmpty() && nums[list.peekLast()] < nums[i])   
                list.pollLast();
            list.addLast(i);
            if (list.peekFirst() == i - k)
                list.pollFirst();
            if (i >= k - 1)
                ans[index++] = nums[list.peekFirst()];
        }
        return ans;
    }
}
** Solution Python3 **
** 176ms, 49.00% **
** 19.5MB, 88.46% **
class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        if (nums == None or len(nums) < k or k < 1) :
            return []
        ans = []
        q = collections.deque()
        for i in range(len(nums)) :
            while (len(q) != 0 and nums[q[-1]] < nums[i]) :
                q.pop()
            q.append(i)
            if (q[0] == i - k) :
                q.popLeft()
            if (i >= k - 1) :
                ans.append(nums[q[0]])
        return ans;
posted @ 2020-02-09 00:34  willwuss  阅读(119)  评论(0编辑  收藏  举报