Greatest difference between numbers in list I found this problem today and eventually came up with a solution. I'm interested in knowing other ways to solve it. You have a list of unsorted integers, and have to compute the greatest difference between list[j] - list[i] such that i &lt; j.

Here's my code:

#include &lt;stdio.h&gt;

// remember the minimum to the left
static int _cached_max(int min, int n, int const* list)
{
  if(n &lt; 1){
    return 0x80000000;
  }

  int max_index = 0;
  for(int i = 1; i &lt; n; ++i){
    if(list[i] &gt;= list[max_index]){
      max_index = i;
    }
  }

  // I know you can check this condition inside the loop above by keeping
  // some extra variables, keeping it here for readability
  for(int i = 0; i &lt; max_index; ++i){
    if(list[i] &lt; min){
      min = list[i];
    }
  }

  int this = list[max_index] - min;
  int next = _cached_max(min, n - max_index - 1, list + max_index + 1);

  return this &gt; next ? this : next;
}

int custom_max(int n, int const* list)
{
  return _cached_max(list[0], n - 1, list + 1);
}

int main(int argc, char* argv[])
{
  int list[] = {12,21,10,20,9,18};
  int max = custom_max(sizeof list / sizeof list[0], list);

  printf("max = %d\n", max);

  return 0;
}


What is the optimal solution to this problem?

Update:

Here's some sample inputs and outputs:

F( [10;4;5;0;8] ) = 8
F( [10;7;16;5;11;3;9;0] ) = 9 
F( [4;5;0;1;2;3;1;8] ) = 8
F( [12;21;10;20;9;18] ) = 10
F( [5;4] ) = -1
Consider that the greatest difference of the following 2 sets exceeds the int range.  For a more robust solution, return a wider type or detect failure.

{INT_MIN, INT_MAX}
{INT_MAX, INT_MIN}

// int custom_max(int n, int const* list)
long long custom_max(int n, int const* list)




Better to use size_t for array indexing.  int may be too narrow.



A solution in liner time, as answered by @janos, is do-able, yet a few changes are needed to handle an ever decreasing list like {10,8,7,4,0}.

For each element arr[i] from 1 to n-1, find if the difference of that element and the prior minimum is a greater difference.

Then update the minimum.

// Detect rare cases when long long and int have similar ranges.
#include &lt;limits.h&gt;
#if LLONG_MIN/2 &gt; INT_MIN || LLONG_MAX/2 &lt; INT_MIN
#error Need wider type
#endif

long long custom_max(size_t n, int const* list) {
   if (n &lt; 2) {
     // Handle pathological case.
     // Avoid magic number
     // return 0x80000000;
     return LLONG_MIN;
   }
   int min = list[0];
   long long maxdiff = LLONG_MIN;
   for (size_t i = 1; i &lt; n; i++) { 
     long long diff = (long long) list[i] - min;
     if (diff &gt; maxdiff) {
       maxdiff = diff;
     }
     if (list[i] &lt; min) {
       min = list[i];
     }
   }
   return maxdiff;
}