C'est un problème du cours Introduction aux algorithmes :
Vous avez un tableau avec n des nombres entiers positifs aléatoires (le tableau n'est pas pas besoin d'être trié ou que les éléments soient uniques). Proposez un O(n) algorithme pour trouver la plus grande somme d'éléments, qui est divisible par n .
Il est relativement facile de le trouver dans O(n 2 ) en utilisant la programmation dynamique et en stockant la plus grande somme avec le reste 0, 1, 2,..., n - 1. Ceci est un code JavaScript :
function sum_mod_n(a)
{
var n = a.length;
var b = new Array(n);
b.fill(-1);
for (var i = 0; i < n; i++)
{
var u = a[i] % n;
var c = b.slice();
for (var j = 0; j < n; j++) if (b[j] > -1)
{
var v = (u + j) % n;
if (b[j] + a[i] > b[v]) c[v] = b[j] + a[i];
}
if (c[u] == -1) c[u] = a[i];
b = c;
}
return b[0];
}
Il est également facile de le trouver dans O(n) pour les éléments contigus, en stockant les sommes partielles MOD n. Autre exemple :
function cont_mod_n(a)
{
var n = a.length;
var b = new Array(n);
b.fill(-1);
b[0] = 0;
var m = 0, s = 0;
for (var i = 0; i < n; i++)
{
s += a[i];
var u = s % n;
if (b[u] == -1) b[u] = s;
else if (s - b[u] > m) m = s - b[u];
}
return m;
}
Mais qu'en est-il O(n) dans le cas général ? Toute suggestion sera appréciée ! Je pense que cela a quelque chose à voir avec l'algèbre linéaire, mais je ne sais pas exactement quoi.
EDIT : Est-ce que cela peut être fait dans O(n log n) ?