1

Is there any other best way to take 5 maximum numbers from 3 sorted arrays as in the code below:

Update:

  1. Below code gives me the result, but I am not sure if this is only way

  2. Input arrays may contain duplicates, but result must not

  3. Efficient means we require less iterations while getting to the result.

  4. I am looking for linq specific answer.

private void Take5MaxNumbers()
{
    var a1 = new[] { 10, 25, 45, 65, 76 };
    var a2 = new[] { 32, 43, 54, 62, 78, 85, 93, 102 };
    var a3 = new[] { 54, 74, 98, 105 };


    var finalArray = a1.Union(a2).Union(a3).OrderByDescending(x => x).Take(5);

    foreach (var item in finalArray)
    {
        Console.Write(item + " ");
    }
}

// Output:
105 102 98 93 85
svick
  • 236,525
  • 50
  • 385
  • 514
Dinesh
  • 3,652
  • 2
  • 25
  • 35

3 Answers3

2

Iterate 5 steps of merge sort for 3 arrays: this could be accomplished with an array of three elements holding the largest values of each array, then finding the maximum and index of the maximum. (if the index is 2 (from 0..2), replace that element from the last presorted array.)

The steps to do this [efficiently] with linq would probably require these steps --

Community
  • 1
  • 1
Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
  • +1 for optimal solution. OP needs unique values, so algorithm may need more than 5 steps to finish. – default locale Mar 04 '13 at 06:20
  • @DnshPly9 Asking that doesn't make much sense. If you need some custom algorithm, it's usually best to write it imperatively, without LINQ. That's because LINQ was not made for writing custom efficient low-level algorithms and it's not good at it. But you could write it in a way that is compatible with LINQ, e.g. `new[] { a1, a2, a3 }.Select(a => a.Reverse()).Merge().Take(5)` (where `Merge()` is a method you would write that implements merge sort). Is that what you're looking for? – svick Mar 04 '13 at 07:08
1

The best way to find out the top 5 element from sorted array is to compare last element of each array get max and the compare last element of each array leaving the previous founded element.

below is the two way for doing this task first one is using only basic types and is the most efficient way, no extra loop no extra comparison no extra memory consumption, just pass the index of elements that need to be match with another one and calculate which is the next index to be match for each given array.

Fist one is this : go through the link :-

Most efficient way to find max top 5 number from three given sorted array

Second one is this :-

int[] Array1 = { 09, 65, 87, 89, 888 };
int[] Array2 = { 1, 13, 33, 49, 921 };
int[] Array3 = { 22, 44, 66, 88, 110 };

int [] MergeArr = Array1.Concat(Array2).Concat(Array3).ToArray();
Array.Sort(MergeArr);
int [] Top5Number = MergeArr.Reverse().Take(5).ToArray() 

Most efficient way to find max top 5 number from three given sorted array

Rohit
  • 1,653
  • 1
  • 13
  • 5
0

You can take the top 5 elements in each array and then finally order by descending.

var a1_5 = a1.Reverse().Take(5).Reverse();
var a2_5 = a2.Reverse().Take(5).Reverse();
var a3_5 = a3.Reverse().Take(5).Reverse();
var resultArray = (a1_5.Union(a2_5)).Union(a3_5).OrderByDescending(x=>x).Take(5);

This way your sorting method "OrderByDescending" will have less inputs to process and better performance.

Rockstart
  • 2,337
  • 5
  • 30
  • 59
  • 2
    Yes, it's an obvious optimisation, but OP states that it's not guaranteed that `a1` doesn't have duplicates. Also, last reverse is quite pointless (next step is sorting anyway) – default locale Mar 04 '13 at 06:48