Je peux le faire en O (n). Faites-moi savoir quand vous voulez la réponse. Notez qu'il s'agit simplement de parcourir le tableau une fois sans tri, etc ... Je dois également mentionner qu'il exploite la commutativité de l'addition et n'utilise pas de hachage mais gaspille de la mémoire.
en utilisant le système; using System.Collections.Generic;
/ * Une approche O (n) existe en utilisant une table de recherche. L'approche consiste à stocker la valeur dans un "bac" qui peut être facilement recherché (par exemple, O (1)) s'il s'agit d'un candidat pour une somme appropriée.
par exemple,
pour chaque a [k] du tableau, nous plaçons simplement le it dans un autre tableau à l'emplacement x - a [k].
Supposons que nous ayons [0, 1, 5, 3, 6, 9, 8, 7] et x = 9
Nous créons un nouveau tableau,
index valeur
9 - 0 = 9 0
9 - 1 = 8 1
9 - 5 = 4 5
9 - 3 = 6 3
9 - 6 = 3 6
9 - 9 = 0 9
9 - 8 = 1 8
9 - 7 = 2 7
ALORS, les seules valeurs qui comptent sont celles qui ont un index dans la nouvelle table.
Donc, disons que lorsque nous atteignons 9 ou égal, nous voyons si notre nouveau tableau a l'indice 9 - 9 = 0. Puisqu'il sait que toutes les valeurs qu'il contient s'ajouteront à 9. (notez dans cette cause il est évident qu'il n'y a que 1 possible mais il peut contenir plusieurs valeurs d'index que nous devons stocker).
Donc, ce que nous finissons par faire, c'est de n'avoir à parcourir le tableau qu'une seule fois. Parce que l'addition est commutative, nous obtiendrons tous les résultats possibles.
Par exemple, lorsque nous arrivons à 6, nous obtenons l'index dans notre nouvelle table sous la forme 9 - 6 = 3. Puisque la table contient cette valeur d'index, nous connaissons les valeurs.
Il s'agit essentiellement de troquer la vitesse contre la mémoire. * /
namespace sum
{
class Program
{
static void Main(string[] args)
{
int num = 25;
int X = 10;
var arr = new List<int>();
for(int i = 0; i <= num; i++) arr.Add((new Random((int)(DateTime.Now.Ticks + i*num))).Next(0, num*2));
Console.Write("["); for (int i = 0; i < num - 1; i++) Console.Write(arr[i] + ", "); Console.WriteLine(arr[arr.Count-1] + "] - " + X);
var arrbrute = new List<Tuple<int,int>>();
var arrfast = new List<Tuple<int,int>>();
for(int i = 0; i < num; i++)
for(int j = i+1; j < num; j++)
if (arr[i] + arr[j] == X)
arrbrute.Add(new Tuple<int, int>(arr[i], arr[j]));
int M = 500;
var lookup = new List<List<int>>();
for(int i = 0; i < 1000; i++) lookup.Add(new List<int>());
for(int i = 0; i < num; i++)
{
// Check and see if we have any "matches"
if (lookup[M + X - arr[i]].Count != 0)
{
foreach(var j in lookup[M + X - arr[i]])
arrfast.Add(new Tuple<int, int>(arr[i], arr[j]));
}
lookup[M + arr[i]].Add(i);
}
for(int i = 0; i < arrbrute.Count; i++)
Console.WriteLine(arrbrute[i].Item1 + " + " + arrbrute[i].Item2 + " = " + X);
Console.WriteLine("---------");
for(int i = 0; i < arrfast.Count; i++)
Console.WriteLine(arrfast[i].Item1 + " + " + arrfast[i].Item2 + " = " + X);
Console.ReadKey();
}
}
}