Reputation: 4094
Say I have an array of integers A
of length N
, also I have an integer L
<= N
.
What I am trying to find is the minimum of the range [0, L-1], [1,L], [2,L+1]....[N-L,N-1]
(like a moving window of length L
from left to right)
My algorithm now is O(N lg N) with O(N lg N) preprocess:
A[0...L-1]
in a multi-set S
, also store the number in a queue Q
in order. The minimum of [0, L-1] is simply the first element of S
. O(N lg N)Q
, find this element in S
and delete it. Then push A[L]
in S
. The minimum of [1, L] is simply the first element of S
. O(lg N)Total is O(N lg N).
I wonder if there is any algorithm which can achieve better than this with following requirements:
I have done some research on RMQ, the nearest method I found is using sparse table which achieve O(1) query time but O(N lg N) preprocess time. Another method which reduce RMQ to LCA problem can meet the requirements but it needs some restriction on the array A
.
So is it possible that, with no restriction on A
, the requirements can be fulfilled when solving my problem?
Upvotes: 1
Views: 158
Reputation: 43477
Yes, use a deque. We will keep the elements sorted ascendingly, so the first element is always the minimum in [i - L + 1, i]
, for the current position i
. We won't keep actual elements, but their positions.
d = empty deque
for i = 0 to n-1:
// get rid of too old elements
while !d.empty && i - d.front + 1 > L:
d.pop_front()
// keep the deque sorted
while !d.empty && A[d.back] > A[i]
d.pop_back()
d.push_back(i)
// A[d.front] is the minimum in `[i - L + 1, i]
Since every element enters and leaves the deque at most once, this is O(n)
.
Upvotes: 3