Question:
A long array A[] is given to you. There is a sliding window of size w which is moving from the very left of the array to the very right. You can only see the w numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example:
The array is [1 3 -1 -3 5 3 6 7], and w is 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
Input: A long array A[], and a window width w
Output: An array B[], B[i] is the maximum value of from A[i] to A[i+w-1]
Requirement: Find a good optimal way to get B[i]
http://leetcode.com/2011/01/sliding-window-maximum.html
////////////
// Option A: Using MaxQueue
//
// What is max queue, similar to max stack
private static class MaxQueue
{
private Queue<Integer> queue = new LinkedList<>();
private Stack<Integer> max = new Stack<>();
void offer(Integer t)
{
if (t == null)
return;
queue.offer(t);
if (max.empty() || t >= max.peek())
max.push(t);
}
Integer poll()
{
if (queue.isEmpty())
return null;
Integer t = queue.poll();
if (t >= max.peek())
max.pop();
return t;
}
Integer max()
{
if (max.empty())
return null;
return max.peek();
}
}
// Time: O(n)
// Space: O(n + w)
public int[] slidingWindowMax(int[] A, int w)
{
// Assumptions:
// A not null, not empty, length must >= w
// Init MaxQueue
MaxQueue maxQueue= new MaxQueue();
for (int i = 0 ; i < w ; i ++)
{
maxQueue.offer(A[i]);
}
// Result
int[] B = new int[A.length - w + 1];
B[0] = maxQueue.max();
for (int i = w ; i < A.length ; i ++)
{
maxQueue.poll();
maxQueue.offer(A[i]);
B[i - w + 1] = maxQueue.max();
}
return B;
}
/////////////////
// Option B: Dequeue
//
// It has a better option without using extra stack.
//
// Time: O(n)
// Space: O(n)
public int[] slidingWindowMax(int[] A, int w)
{
// Deque
// See //
// [end ... head]
// Order : >>
// Every time push new element into end, still keep the order
//
Deque<Integer> queue = new LinkedList<>();
// Init deque
for (int i = 0 ; i < w ; i ++)
{
offer(queue, A[i]);
}
// Result
int[] B = new int[A.length - w + 1];
B[0] = max(queue);
for (int i = w ; i < A.length ; i ++)
{
queue.offer(A[i]);
B[i - w + 1] = max(queue);
}
return B;
}
private void offer(Deque<Integer> queue, int t)
{
while (!queue.isEmpty() && queue.peekLast() <= t)
{
queue.pollLast();
}
queue.offerLast(t);
}
private void max(Dequeue<Integer> queue)
{
return queue.peekFirst();
}[LeetCode] Sliding Window Maximum
原文:http://7371901.blog.51cto.com/7361901/1605492