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的下标。
- 如果deque为空,直接把下标i放deque,放入过程结束;
- 如果deque不为空,取出当前deque队尾存放的下表,假设为j;
1). 如果nums[j]>nums[i], 直接把下标i放入队尾,放入过程结束;
2). 如果nums[j]<=nums[i],把j从deque中弹出,继续deque的放入规则; - 如果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;