ฉันทำได้ใน O (n) แจ้งให้เราทราบเมื่อคุณต้องการคำตอบ โปรดทราบว่ามันเกี่ยวข้องกับการข้ามอาร์เรย์เพียงครั้งเดียวโดยไม่มีการเรียงลำดับ ฯลฯ ... ฉันควรพูดถึงด้วยว่ามันใช้ประโยชน์จากการสับเปลี่ยนของการเพิ่มและไม่ใช้แฮช แต่ทำให้เสียหน่วยความจำ
ใช้ระบบ; ใช้ System.Collections.Generic;
/ * มีแนวทาง O (n) โดยใช้ตารางการค้นหา วิธีการนี้คือการจัดเก็บค่าใน "bin" ที่สามารถค้นหาได้ง่าย (เช่น O (1)) หากเป็นตัวเลือกสำหรับผลรวมที่เหมาะสม
เช่น,
สำหรับแต่ละ a [k] ในอาร์เรย์เราเพียงแค่ใส่ไว้ในอาร์เรย์อื่นที่ตำแหน่ง x - a [k]
สมมติว่าเรามี [0, 1, 5, 3, 6, 9, 8, 7] และ x = 9
เราสร้างอาร์เรย์ใหม่
ค่าดัชนี
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
จากนั้นค่าเดียวที่สำคัญคือค่าที่มีดัชนีในตารางใหม่
ดังนั้นสมมติว่าเมื่อเราถึง 9 หรือเท่ากับเราจะดูว่าอาร์เรย์ใหม่ของเรามีดัชนี 9 - 9 = 0 หรือไม่เนื่องจากเรารู้ว่าค่าทั้งหมดที่มีจะเพิ่มเป็น 9 (โปรดสังเกตในสาเหตุนี้ชัดเจนมีเพียง 1 เป็นไปได้ แต่อาจมีค่าดัชนีหลายค่าซึ่งเราจำเป็นต้องจัดเก็บ)
ดังนั้นสิ่งที่เราทำได้อย่างมีประสิทธิภาพก็คือการเลื่อนผ่านอาร์เรย์เพียงครั้งเดียว เนื่องจากการเพิ่มเป็นการสับเปลี่ยนเราจะได้ผลลัพธ์ที่เป็นไปได้ทั้งหมด
ตัวอย่างเช่นเมื่อเราถึง 6 เราจะได้ดัชนีในตารางใหม่เป็น 9 - 6 = 3 เนื่องจากตารางมีค่าดัชนีนั้นเราจึงรู้ค่า
นี่คือการแลกเปลี่ยนความเร็วสำหรับหน่วยความจำเป็นหลัก * /
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();
}
}
}