Sunday 28 October, 2012

Q) Given an array of integers , find 3 indexes i,j,k such that, i<j<k and a[i] < a[j] < a[k]

Ans) Let's take an example

A = {4, 1, 3, 5, 8}

In the above example, we've  {1,3,5}, {1,3,8}, ... which satisfies the condition given in the question.
So that means for each element, we've to see whether there is a smaller element to the left of that element and a bigger element to the right of that element.
That'll give us a brute force approach of O(n^2)
     for (int i=0; i<n; i++) {
          leftIndex = rightIndex = -1;
          for (int left=0; left<i; left++)  {
               if (a[left] < a[i]) {
                      leftIndex = left;
                      break;
                }
         }
         // Similarly find right index which is greater than a[i]
         if (leftIndex != -1 && rightIndex != -1) {
              printf("%d %d %d", leftIndex, i, rightIndex);
              return;
         }
    }

OK. That's fine. Now how to optimize this solution.
Instead of searching in left and right for a smaller and bigger element each time, we can store the minimum in the left and maximum in the right for each element. So we can save the operation to check whether there is a smaller element exist in left or not.

So let's take 2 new arrays, leftMin[] and rightMax[] such that leftMin[i] stores the INDEX of minimum element from 0 to i, and rightMax[i] stores index of maximum element from 'n' to i.
Then it's just a matter of checking a[i] with leftMin[i] and rightMax[i] to get the solution. It works in O(N) run time complexity and O(N) space complexity.

eg: If array is A = {4, 1, 3, 5, 8}, we form following arrays:
leftMin = { 0, 1, 1, 1, 1}  // Index of 1 in original array is 1
rightMax = {4,4,4,4,4}  // Index of 8 in original array is 4

Sample Code
==========
// Initialize 2 arrays
leftMinIndex = 0; rightMaxIndex = n-1;
for (int i=1, j=n-1; i<n; i++, j--)
{
     if (a[i] < a[leftMinIndex])
     {
         leftMinIndex = i;
     }
     leftMin[i] = leftMinIndex;

     // Initialize rightMax

     if (a[i] > a[rightMaxIndex])
     {
         rightMaxIndex = i;
     }
     rightMax[i] = rightMaxIndex;

}

// Now traverse input array again to find the output
for (int i=0; i<n; i++)
{
    if (a[i] > leftMin[i] && a[i] < rightMax[i]) {
          printf("%d,  %d,  %d", leftMin[i], i, rightMax[i]);
          return;
    }
}
printf("Triplets not found");
}

No comments:

Post a Comment