2

You are given with three sorted arrays ( in ascending order), you are required to find a triplet ( one element from each array) such that distance is minimum. Distance is defined like this : If a[i], b[j] and c[k] are three elements then

distance = max{abs(a[i]-b[j]),abs(a[i]-c[k]),abs(b[j]-c[k])}

Please give a solution in O(n) time complexity

Saeed Amiri
  • 22,252
  • 5
  • 45
  • 83
tcp
  • 289
  • 3
  • 5
  • 15
  • Can you post the best solution you managed to come up with? Or at least an attempt or two that didn't work? – Bernhard Barker Oct 18 '13 at 12:32
  • Solution is explained in http://placementsindia.blogspot.in/2007/09/sorting-mergesort.html. But couldn't understand it. – tcp Oct 18 '13 at 12:41

2 Answers2

4

Linear time algorithm:

double MinimalDistance(double[] A, double[] B, double[] C)
{
    int i,j,k = 0;
    double min_value = infinity;
    double current_val;
    int opt_indexes[3] = {0, 0, 0);

    while(i < A.size || j < B.size || k < C.size)
    {
         current_val = calculate_distance(A[i],B[j],C[k]);
         if(current_val < min_value)
         {
               min_value = current_val;
               opt_indexes[1] = i;
               opt_indexes[2] = j;
               opt_indexes[3] = k;
         }    

         if(A[i] < B[j] && A[i] < C[k] && i < A.size)
             i++;
         else if (B[j] < C[k] && j < B.size)
             j++;
         else
             k++; 
    }

    return min_value;
}

In each step you check the current distance, then increment the index of the array currently pointing to the minimal value. each array is iterated through exactly once, which mean the running time is O(A.size + B.size + C.size).

if you want the optimal indexes instead of the minimal values, you can return opt_indexes instead of min_value.

dcaswell
  • 3,137
  • 2
  • 26
  • 25
Ron Teller
  • 1,880
  • 1
  • 12
  • 23
1

Suppose we have just one sorted array, then 3 consecutive elements which have less possible distances are the desired solution. Now when we have three arrays, just merge them all and make a big sorted array ABC (this can be done in O(n) by merge operation in merge-sort), just keep a flag to determine which element belongs in which original array. Now you have to find three consecutive elements in array like this:

a1,a2,b1,b2,b3,c1,b4,c2,c3,c4,b5,b6,a3,a4,a5,....

and here consecutive means they belong to the 3 different group in consecutive order, e.g: a2,b3,c1 or c4,b6,a3.

Now finding this tree elements is not hard, sure smallest and greatest one should be last and first of a elements of first and last group in some triple, e.g in the group: [c2,c3,c4],[b5,b6],[a3,a4,a5], we don't need to check a4,a5,c2,c3 is clear that possible solution in this case is among c4,[b5,b6],a5, also we don't need to compare c4 with b5,b6, or a5 with b5,b6, sure distance is made by a5-c4 (in this group). So we can start from left and keep track of last element and update best possible solution in each iteration by just keeping the last visited value of each group.

Example (first I should say that I didn't wrote the code because I think this is OP's task not me):

Suppose we have this sequences after sorted array:

a1,a2,b1,b2,b3,c1,b4,c2,c3,c4,b5,b6,a3,a4,a5,....

let iterate step by step:

We need to just keep track of last item for each item from our arrays, a is for keeping track of current best a_i, b for b_i, and c for c_i. suppose at first a_i=b_i=c_i=-1,

in the first step a will be a1, in the next step

a=a2,b=-1,c=-1
a=a2,b=b1,c=-1
a=a2,b=b2,c=-1
a=a2,b=b3,c=-1,
a=a2,b=b3,c=c1,

At this point we save current pointers (a2,b3,c1) as a best value for difference,

In the next step:

a=a2,c=c1,b=b4

Now we compare the difference of b4-a2 with previously best option, if is better, we save this pointers as a solution upto now and we proceed:

a=a2,b=b4,c=c2 (again compare and if needed update the best solution),
a=a2,b=b4,c=c3 (again ....)
a=a2,b=b4,c=c4 (again ....)
a=a2, b=b5,c=c4, ....

Ok if is not clear from the text, after merge we have (I'll suppose all of array have at least one element):

solution = infinite; a=b=c=-1, bestA=bestB=bestC=1;

for (int i=0;i<ABC.Length;i++)
{
    if(ABC[i].type == "a") // type is a flag determines 
                           // who is the owner of this element
    {
        a=ABC[i].Value; 
        if (b!=-1&&c!=-1)
        {
          if (max(|a-b|,|b-c|,|a-c|) < solution)
          {
            solution =  max(|a-b|,|b-c|,|a-c|);
            bestA= a,bestB = b,bestC = c;
          }
        }
    }
    // and two more if for type "b" and "c"
}

Sure there is more elegant algorithm than this, but I see you had problem with your link, so I guess this trivial way of looking at problem makes it easier, afterward you can understand your own link.

Saeed Amiri
  • 22,252
  • 5
  • 45
  • 83
  • The base step of single array what you have explained is easy to understand.eg if array is 2,3,6,8,9--triple would be (6,8,9) since 9-6=3 is least.When you have different arrays i merge and create one sorted array(assume I have stored information about from which array these elements have come from).How to proceed from this step??Can you explain with an example?? – tcp Oct 18 '13 at 14:01
  • @PavanRavishankar, I tried to elaborate it with sample and pseudo code. – Saeed Amiri Oct 18 '13 at 15:56