Puedo hacerlo en O (n). Avísame cuando quieras la respuesta. Tenga en cuenta que implica simplemente atravesar la matriz una vez sin ordenar, etc. También debo mencionar que explota la conmutatividad de la suma y no usa hashes sino que desperdicia memoria.
utilizando el sistema; usando System.Collections.Generic;
/ * Existe un enfoque O (n) mediante el uso de una tabla de búsqueda. El enfoque consiste en almacenar el valor en un "contenedor" que se puede buscar fácilmente (por ejemplo, O (1)) si es candidato para una suma adecuada.
p.ej,
para cada a [k] en la matriz simplemente la colocamos en otra matriz en la ubicación x - a [k].
Supongamos que tenemos [0, 1, 5, 3, 6, 9, 8, 7] yx = 9
Creamos una nueva matriz,
valor de índices
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
ENTONCES, los únicos valores importantes son los que tienen un índice en la nueva tabla.
Entonces, digamos que cuando alcanzamos 9 o igual, vemos si nuestra nueva matriz tiene el índice 9 - 9 = 0. Como lo sabemos, todos los valores que contiene se sumarán a 9. (tenga en cuenta que es obvio que solo hay 1 posible, pero puede tener múltiples valores de índice que necesitamos almacenar).
Entonces, efectivamente, lo que terminamos haciendo es tener que movernos a través de la matriz una sola vez. Como la suma es conmutativa, terminaremos con todos los resultados posibles.
Por ejemplo, cuando llegamos a 6 obtenemos el índice en nuestra nueva tabla como 9 - 6 = 3. Como la tabla contiene ese valor de índice, conocemos los valores.
Esto es esencialmente cambiar la velocidad por la memoria. * /
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();
}
}
}