Ich kann es in O (n) tun. Lassen Sie mich wissen, wann Sie die Antwort wollen. Beachten Sie, dass das Array einfach einmal ohne Sortierung usw. durchlaufen wird. Ich sollte auch erwähnen, dass es die Kommutativität der Addition ausnutzt und keine Hashes verwendet, sondern Speicher verschwendet.
mit System; using System.Collections.Generic;
/ * Ein O (n) -Ansatz existiert unter Verwendung einer Nachschlagetabelle. Der Ansatz besteht darin, den Wert in einem "Behälter" zu speichern, der leicht nachgeschlagen werden kann (z. B. O (1)), wenn es sich um einen Kandidaten für eine geeignete Summe handelt.
z.B,
Für jedes a [k] im Array setzen wir es einfach in ein anderes Array an der Stelle x - a [k].
Angenommen, wir haben [0, 1, 5, 3, 6, 9, 8, 7] und x = 9
Wir erstellen ein neues Array,
indiziert Wert
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
DANN sind nur diejenigen Werte von Bedeutung, die einen Index in der neuen Tabelle haben.
Wenn wir also 9 oder gleich erreichen, sehen wir, ob unser neues Array den Index 9 - 9 = 0 hat. Da wir wissen, dass alle darin enthaltenen Werte zu 9 addiert werden (beachten Sie, dass es in diesem Fall offensichtlich nur einen gibt 1 möglich, aber es kann mehrere Indexwerte enthalten, die wir speichern müssen).
Am Ende müssen wir uns also nur einmal durch das Array bewegen. Da die Addition kommutativ ist, erhalten wir alle möglichen Ergebnisse.
Wenn wir zum Beispiel 6 erreichen, erhalten wir den Index als 9 - 6 = 3 in unsere neue Tabelle. Da die Tabelle diesen Indexwert enthält, kennen wir die Werte.
Dies ist im Wesentlichen ein Kompromiss zwischen Geschwindigkeit und Speicher. * /
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();
}
}
}