Saya bisa melakukannya di O (n). Beri tahu saya jika Anda menginginkan jawabannya. Perhatikan itu melibatkan hanya melintasi array sekali tanpa penyortiran, dll ... Saya harus menyebutkan juga bahwa itu mengeksploitasi komutatifitas penambahan dan tidak menggunakan hash tetapi membuang memori.
menggunakan Sistem; menggunakan System.Collections.Generic;
/ * Pendekatan O (n) ada dengan menggunakan tabel pencarian. Pendekatannya adalah dengan menyimpan nilai dalam "bin" yang dapat dengan mudah dicari (misalnya, O (1)) jika itu adalah kandidat untuk jumlah yang sesuai.
misalnya,
untuk setiap a [k] dalam larik kita cukup meletakkannya di larik lain pada lokasi x - a [k].
Misalkan kita memiliki [0, 1, 5, 3, 6, 9, 8, 7] dan x = 9
Kami membuat array baru,
nilai indeks
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
MAKA satu-satunya nilai yang penting adalah nilai yang memiliki indeks ke dalam tabel baru.
Jadi, katakanlah ketika kita mencapai 9 atau sama, kita melihat apakah array baru kita memiliki indeks 9 - 9 = 0. Karena kita tahu bahwa semua nilai yang dikandungnya akan bertambah menjadi 9. (perhatikan karena ini jelas hanya ada 1 mungkin satu tetapi mungkin memiliki beberapa nilai indeks di dalamnya yang perlu kita simpan).
Jadi secara efektif apa yang akhirnya kita lakukan adalah hanya berpindah melalui array sekali. Karena penambahan bersifat komutatif, kami akan mendapatkan semua hasil yang mungkin.
Misalnya, ketika kita mendapatkan nilai 6 kita mendapatkan indeks ke dalam tabel baru kita sebagai 9 - 6 = 3. Karena tabel tersebut berisi nilai indeks, kita mengetahui nilainya.
Ini pada dasarnya menukar kecepatan untuk memori. * /
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();
}
}
}