Given an array arr[], find the maximum j – i such that arr[j] > arr[i].
Examples:
Input: {34, 8, 10, 3, 2, 80, 30, 33, 1}
Output: 6 (j = 7, i = 1)
Method 2 (Efficient)To solve this problem, we need to get two optimum indexes of arr[]: left index i and right index j.
For an element arr[i], we do not need to consider arr[i] for left index if there is an element smaller than arr[i] on left side of arr[i]. Similarly, if there is a greater element on right side of arr[j] then we do not need to consider this j for right index.
So we construct two auxiliary arrays LMin[] and RMax[] such that LMin[i] holds the smallest element on left side of arr[i] including arr[i], and RMax[j] holds the greatest element on right side of arr[j] including arr[j]. After constructing these two auxiliary arrays, we traverse both of these arrays from left to right. While traversing LMin[] and RMa[] if we see that LMin[i] is greater than RMax[j], then we must move ahead in LMin[] (or do i++) because all elements on left of LMin[i] are greater than or equal to LMin[i]. Otherwise we must move ahead in RMax[j] to look for a greater j – i value.
/* For a given array arr[], returns the maximum j-i such that
arr[j] > arr[i] */
int
maxIndexDiff(
int
arr[],
int
n)
{
int
maxDiff;
int
i, j;
int
RMax[] =
new
int
[n];
int
LMin[] =
new
int
[n];
/* Construct LMin[] such that LMin[i] stores the minimum value
from (arr[0], arr[1], ... arr[i]) */
LMin[
0
] = arr[
0
];
for
(i =
1
; i < n; ++i)
LMin[i] = min(arr[i], LMin[i -
1
]);
/* Construct RMax[] such that RMax[j] stores the maximum value
from (arr[j], arr[j+1], ..arr[n-1]) */
RMax[n -
1
] = arr[n -
1
];
for
(j = n -
2
; j >=
0
; --j)
RMax[j] = max(arr[j], RMax[j +
1
]);
/* Traverse both arrays from left to right to find optimum j - i
This process is similar to merge() of MergeSort */
i =
0
; j =
0
; maxDiff = -
1
;
while
(j < n && i < n)
{
if
(LMin[i] < RMax[j])
{
maxDiff = max(maxDiff, j - i);
j = j +
1
;
}
else
i = i +
1
;
}
return
maxDiff;
}
Brute force O(N^2)
int
maxIndexDiff(
int
arr[],
int
n)
{
int
maxDiff = -
1
;
int
i, j;
for
(i =
0
; i < n; ++i)
{
for
(j = n -
1
; j > i; --j)
{
if
(arr[j] > arr[i] && maxDiff < (j - i))
maxDiff = j - i;
}
}
return
maxDiff;
}
http://articles.leetcode.com/2011/05/a-distance-maximizing-problem.html
ask yourself if you would choose index a or b as a potential starting point. Clearly, you would never choose index b as the starting point.
Generally, we want to choose only starting points with no such lines that are shorter to its left side. From the diagram above, only lines of index 0, 1, 3, 4 are valid starting points.
Once we gather all valid starting points by scanning once from left to right, we are able to obtain the maximum distance by scanning backwards.
O(N^2)
int
maxIndexDiff(
int
arr[],
int
n)
{
int
maxDiff = -1;
int
i, j;
for
(i = 0; i < n; ++i)
{
for
(j = n-1; j > i; --j)
{
if
(arr[j] > arr[i] && maxDiff < (j - i))
{
maxDiff = j - i; break; }
}
}
return
maxDiff;
}
Widest Inversion
Two sorted elements with maximum distance in an unsorted array
Problem: Given an unsorted array, find two indexes in the array such that arr[i] < arr[j] and j-i is maximum.
Example: If the array is [7, 3, 9, 2, 1, 11, 0], 7 and 11 are the solution.
void findMaxDistanceApart (int arr[])
{
if (arr.length<=1)
return;
int indexOfLeftMin [] = new int [arr.length];
int indexOfRightMax[] = new int [arr.length];
// below loop fills first array such that value at every index
// tells the position of the minimum element present in the left of that index
indexOfLeftMin[0] = 0;
for (int i=1; i< arr.length; i++)
{
int currMin = arr[indexOfLeftMin[i-1]];
if (arr[i] < currMin)
{
indexOfLeftMin[i] = i;
} else {
indexOfLeftMin[i] = indexOfLeftMin[i-1];
}
}
// below loop fills second array such that value at every index
// tells the position of the maximum element present in the right of that index
indexOfRightMax[arr.length-1] = arr.length-1;
for (int i=arr.length-2; i >= 0; i--)
{
int currMax = arr[indexOfRightMax[i+1]];
if (arr[i] > currMax)
{
indexOfRightMax[i] = i;
} else {
indexOfRightMax[i] = indexOfRightMax[i+1];
}
}
// find k such that difference between indexOfRightMax[k] and indexOfLeftMin[k] is maximum
int maxDiff = -1;
int i = -1;
int j = -1;
for (int k=0; k < arr.length; k++)
{
int distance = indexOfRightMax[k] - indexOfLeftMin[k];
if (distance > maxDiff)
{
i = indexOfLeftMin[k];
j = indexOfRightMax[k];
}
}
if (i==j)
{
print ("No such pair exists");
return;
}
print ("Two sorted elements maximum distance apart are " + arr[i] + " and " + arr[j]);
print ("And maximum distance is " + (j-i));
}
Read full article from Given an array arr[], find the maximum j - i such that arr[j] > arr[i] | GeeksforGeeks