Sliding Window Maximum
Total Accepted: 22812 Total Submissions: 85476 Difficulty: 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.
For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.
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
Therefore, return the max sliding window as [3,3,5,5,6,7].
Note:
You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.
Follow up:
Could you solve it in linear time?
思路
- 思路1:max heap去求最大,然后指针不断往前走,因为heap删除操作O(k),所以总时间复杂度为O(nk),为下面代码第一个实现
- 思路2:max hashheap求最大,因为hashheap删除操作O(logk),所以总时间复杂度为O(nlogk)
- 思路3:使用deque,deque首处就是最大值所在处,如果后面加入的元素更大,就从之前后面poll出去,如果长度超过了k,就把deque首处元素poll出去. 关键之处在于使用deque储存的是Index,而不是元素值本身. 时间复杂度O(n),为下面代码第二个实现
heap实现
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int size = nums.length;
if (size == 0 || k == 0 || size < k) {
return new int[0];
}
int[] result = new int[size - k + 1];
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(k, Collections.reverseOrder());
for (int x = 0; x < k; x++) {
pq.offer(nums[x]);
}
int i = 0;
int j = k;
while (j < size) {
result[i] = pq.peek();
pq.remove(nums[i++]);
pq.offer(nums[j++]);
}
result[i] = pq.peek();
return result;
}
}
deque实现
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int size = nums.length;
if (size == 0 || k == 0 || size < k) {
return new int[0];
}
int[] result = new int[size - k + 1];
Deque<Integer> deque = new LinkedList<Integer>();
deque.offer(0);
int i = 0;
for (i = 1; i < k; i++) {
while (!deque.isEmpty() && nums[i] >= nums[deque.getLast()]) {
deque.removeLast();
}
deque.offer(i);
}
int index = 0;
result[index++] = nums[deque.getFirst()];
while (i < size) {
if (i - deque.getFirst() >= k) {
deque.removeFirst();
}
while (!deque.isEmpty() && nums[i] >= nums[deque.getLast()]) {
deque.removeLast();
}
deque.offer(i);
i++;
result[index++] = nums[deque.getFirst()];
}
return result;
}
}