Thursday, July 7, 2011

Given an array A of integers, find the maximum difference between two indexes j-i such that A[i] < A[j].

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)

Algorithm:
Run two loops. In the outer loop, pick elements one by one from left. In the inner loop, compare the picked element with the elements starting from right side. Stop the inner loop when you see an element greater than the picked element and keep updating the maximum j-i so far.


#include
/* For a given array arr[], returns the maximum j – i such that
arr[j] > arr[i] */
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; } int main() { int arr[] = {9, 2, 3, 4, 5, 6, 7, 8, 18, 0}; int n = sizeof(arr)/sizeof(arr[0]); int maxDiff = maxIndexDiff(arr, n); printf("\n %d", maxDiff); getchar(); return 0; } Time Complexity: O(n^2) Space Complexity O(1) Method 2 Given by celicom

Algorithm

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.

You Know Ultimate Things we have to found out is maximum distance between minimum element from Lmin array to Maximum element in RMax Array isn't it :)

Here is a draft O(N) algo to find max{j-i,A[j]>A[i]}.
For a given array of numbers A[N] (zero based),
1) Create array B[N]. Init it the following way:
B[0] = A[0];
for(i=1;i=0;--i) C[i] = max(A[i],C[i+1]);
3) Let max_i_j = 0, i=j=0. Now, do this merge type of calculation on B and C:
while(j

/* Utility Functions to get max and minimum of two integers */
int max(int x, int y)
{
return x > y? x : y;
}

int min(int x, int y)
{
return x < y? x : y; } /* 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 *LMin = (int *)malloc(sizeof(int)*n);
int *RMax = (int *)malloc(sizeof(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; } /* Driver program to test above functions */ int main() { int arr[] = {9, 2, 3, 4, 5, 6, 7, 8, 18, 0}; int n = sizeof(arr)/sizeof(arr[0]); int maxDiff = maxIndexDiff(arr, n); printf("\n %d", maxDiff); getchar(); return 0; } Time Complexity: O(n) Auxiliary Space: O(2n)..........................!!!!!!!!! Optimization in 2nd Method we can do it without using lmin array #include
#include

/* Utility Functions to get max and minimum of two integers */
int max(int x, int y)
{
return x > y? x : y;
}

int min(int x, int y)
{
return x < y? x : y; } int maxIndexDiff(int arr[], int n) { int maxDiff; int i, j; int LMin; int *RMax = (int *)malloc(sizeof(int)*n); LMin = arr[0]; /* 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 < RMax[j])
{
maxDiff = max(maxDiff, j-i);
j = j + 1;
}
else
{
LMin = min(LMin,arr[i+1]);
i = i+1;
}
}

return maxDiff;
}
/* Driver program to test above functions */
int main()
{
int arr[] = {2, 9, 3, 4, 5, 6, 7, 8, 18, 8,0};
int n = sizeof(arr)/sizeof(arr[0]);
int maxDiff = maxIndexDiff(arr, n);
printf("\n %d", maxDiff);
getchar();
return 0;
}

Time Complexity: O(n)
Auxiliary Space: O(n)..........................!!!!!!!!!
Run Here http://ideone.com/tNF7Q

No comments :