Sliding Window Maximum solution
Question
from lintcode
Given an array of n integer with duplicate number, and a moving window(size k), move the window at each iteration from the start of the array, find the maximum number inside the window at each moving.
Example
For array [1, 2, 7, 7, 8], moving window size k = 3. return [7, 7, 8]
At first the window is at the start of the array like this
[|1, 2, 7| ,7, 8] , return the maximum 7;
then the window move one step forward.
[1, |2, 7 ,7|, 8], return the maximum 7;
then the window move one step forward again.
[1, 2, |7, 7, 8|], return the maximum 8;
Idea
Source
A Deque is basically a list where you can manipulate the first element and the last element.
Initialize the window by pushing elements into the deque, as long as the elements come in decreasing order, i.e. the first element is the largest and the last element is the smallest. If an element to be inserted break the order, pop elements from the last one until that element can fit into the order.
Then slide the window each time by adding a new element into the deque and lazy-removing an element left out from the window. Lazy-remove means you only do the removal only when the element is at deque top (the first one). This is because when you want to remove nums[i]
, it is assumed that any number before position i
has already been slid out conceptually, while in fact which might have been polled out at an even earlier time.
When an element is to be removed during sliding, there are two possible cases.
Case 1, this element is the max. And the second largest stays in the queue for sure, see inQueue()
. So, we do the removal.
Case 2, this element is not the max, then it was already polled out when larger numbers at later positions enter the deque. Removal is needn't.
public class Solution {
/*
* @param nums: A list of integers
* @param k: An integer
* @return: The maximum number inside the window at each moving
*/
public ArrayList<Integer> maxSlidingWindow(int[] nums, int k) {
// write your code here
ArrayList<Integer> ans = new ArrayList<>();
Deque<Integer> deque = new ArrayDeque<>();
if (nums.length == 0) return ans;
for(int i = 0; i < k - 1; i++) {
inQueue(deque, nums[i]);
}
for(int i = k - 1; i < nums.length; i++) {
inQueue(deque, nums[i]);
ans.add(deque.peekFirst());
outQueue(deque, nums[i - k + 1]);
}
return ans;
}
void inQueue(Deque<Integer> deque, int num) {
while(!deque.isEmpty() && deque.peekLast() < num)
deque.pollLast();
deque.add(num);
}
void outQueue(Deque<Integer> deque, int num) {
if (deque.peekFirst() == num)
deque.pollFirst();
}
};