Given an unsorted array, find the max
j - i
difference between indices such that j > i
and a[j] > a[i]
in O(n)
. I am able to find j
and i
using trivial methods in O(n^2)
complexity but would like to know how to do this in O(n)
?
Input: {9, 2, 3, 4, 5, 6, 7, 8, 18, 0}
Output: 8 ( j = 8, i = 0)
Input: {1, 2, 3, 4, 5, 6}
Output: 5 (j = 5, i = 0)
For brevity's sake I am going to assume all the elements are unique. The algorithm can be extended to handle non-unique element case.
First, observe that if x
and y
are your desired max and min locations respectively, then there can not be any a[i] > a[x]
and i > x
, and similarly, no a[j] < a[y]
and j < y
.
So we scan along the array a
and build an array S
such that S[i]
holds the index of the minimum element in a[0:i]
. Similarly an array T
which holds the index of the maximum element in a[n-1:i]
(i.e., backwards).
Now we can see that a[S[i]]
and a[T[i]]
are necessarily decreasing sequences, since they were the minimum till i
and maximum from n
till i
respectively.
So now we try to do a merge-sort like procedure. At each step, if a[S[head]] < a[T[head]]
, we pop off an element from T
, otherwise we pop off an element from S
. At each such step, we record the difference in the head of S and T if a[S[head]] < a[T[head]]
. The maximum such difference gives you your answer.
EDIT: Here is a simple code in Python implementing the algorithm.
def getMaxDist(arr): # get minima going forward minimum = float("inf") minima = collections.deque() for i in range(len(arr)): if arr[i] < minimum: minimum = arr[i] minima.append((arr[i], i)) # get maxima going back maximum = float("-inf") maxima = collections.deque() for i in range(len(arr)-1,0,-1): if arr[i] > maximum: maximum = arr[i] maxima.appendleft((arr[i], i)) # do merge between maxima and minima maxdist = 0 while len(maxima) and len(minima): if maxima[0][0] > minima[0][0]: if maxima[0][1] - minima[0][1] > maxdist: maxdist = maxima[0][1] - minima[0][1] maxima.popleft() else: minima.popleft() return maxdist
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With