0

The task is to find the maximum three in the array (multiplying three numbers so that their products are the largest).

Array length can be up to 1.000.000

Range of numbers from -1.000.000 to 1.000.000

Question: I understand that first you need to sort the array by quick sort, and then what condition should I select the numbers?

For example, in the sequence:

-17, -12, 1, 3, 4 

(-17) * (- 12) * 4 will work, that is, the multiplication of the three most significant positive numbers will be less.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • Also see: [Max product of the three numbers for a given array of size N](https://stackoverflow.com/questions/2187431/max-product-of-the-three-numbers-for-a-given-array-of-size-n) – default locale Oct 18 '20 at 11:59
  • By the way, you don't really need to sort the whole array to find the three largest/two smallest elements. For this, you only need to iterate through the array and keep track of two/three maximums. This is an O(N) operiation. – default locale Oct 18 '20 at 12:02
  • For larger lists, a simple bubblesort will work, as you need just three iterations to get the three largest numbers on top. You don't care about the rest. Compare the *absolute* values – Hans Kesting Oct 18 '20 at 12:28
  • default locale, thanks! – KevinTrigger Oct 18 '20 at 12:40

2 Answers2

2

Well, for a given sequence, say,

 4, 3, 1, -12, -17 

maximum is either a product of top 3 items:

4 * 3 * 1 == 12

or a product of 2 bottom items and the top one:

-17 * -12 * 4 == 816

Here, the second option provides a better outcome, so the answer is 816. To obtain these top 3 and bottom 2 items you don't have to sort; a simple scan is enough:

private static long TopThreeMaximum(IEnumerable<int> values) {
  long Max1 = long.MinValue;
  long Max2 = long.MinValue;
  long Max3 = long.MinValue;

  long Min1 = long.MaxValue;
  long Min2 = long.MaxValue;

  foreach (int value in values) {
    if (value >= Max1) {
      Max3 = Max2;
      Max2 = Max1;
      Max1 = value;
    }
    else if (value >= Max2) {
      Max3 = Max2;
      Max2 = value;
    }
    else if (value > Max3)
      Max3 = value;

    if (Min1 >= value) {
      Min2 = Min1;
      Min1 = value;
    }
    else if (Min2 > value)
      Min2 = value;
  }

  return Math.Max(Max1 * Max2 * Max3, Max1 * Min1 * Min2);
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • This is a good answer in most cases. We also might have to consider some edge cases. E.g., what if we have only 2 positive values? Then we must multiply 1 positive and 2 negative ones. – Olivier Jacot-Descombes Oct 18 '20 at 12:46
  • 1
    @Olivier Jacot-Descombes: in case we have just `2` positive values only, we'll have the second case: top value (which is positive) and two biggest negative values: `2, 1, -3, -4, -5 => 2 * -4 * -5 == 40` – Dmitry Bychenko Oct 18 '20 at 12:49
1

Since this is a homework I will not provide code for you, but if you follow the following ideas, then you should be able to easily write the code:

  • don't quicksort: it has a complexity of *nlogn and you can do a complexity of n
  • find the three highest positive number
  • find the three lowest negative number (remember -17 is lower than -12)
  • store them separately
  • at the end compute the product of those numbers
  • beware edge cases, like (-20, -10, -4), (20, 0), don't use 0 in any product, unless you cannot reach a positive result

Happy coding!

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175