Dada una matriz S de n enteros, ¿hay elementos a, b, c en S tales que a + b + c = 0? ¿Encuentra todos los tripletes únicos en la matriz que da la suma de cero?

Esta es una variante de 3SUM. Hay muchas formas de resolverlo, y no puede hacerlo mejor que el tiempo de ejecución O (N ^ 2). Una solución:

1. Ordene los enteros en el lugar (clasificación rápida, clasificación de radios MSD, etc.).
2. Iterar a través de los enteros de izquierda a derecha (de i = 0 a i = n-3).
3. Deje que x sea su número entero actual a [i]. Ahora ha reducido el problema a encontrar todos los pares de enteros (y y z) de i + 1 a n-1 de modo que x + a [y] + a [z] sumen 0 para cada i.

  a.sort () # Técnicamente desearía hacer una ordenación in situ.
 para i en xrange (0, n - 2):
     x = a [i]
     y = i + 1
     z = n - 1
     mientras y <z:
         triplet_sum = x + a [y] + a [z]
         si triplet_sum == 0:
             # Encontramos un triple
             rendimiento (x, a [y], a [z])
             y + = 1
             z - = 1
         elif triplet_sum <0:
             y + = 1
         más:
             z - = 1

El tiempo de ejecución es O (N ^ 2), que es óptimo, y el espacio depende de lo que elija (p. Ej., Clasificación rápida y clasificación de radios MSD use O (espacio de registro (N)) y qué hace con el triple (p. Ej., Impresión o el rendimiento sería O (1) mientras que agregar los tripletes a una colección usaría el espacio O (N)).

  1. Ordenar la matriz -> O (nlog (n))
  2. Arregle un elemento e intente encontrar los otros dos, uno por uno -> O (n ^ 2)
  int i = 0;
 para (i = 0; i  0)
             r--;
     }
 }

Complejidad general: O (n ^ 2 + n * log (n)) = O (n ^ 2)

Existe un algoritmo O (N²) simple que no requiere ninguna otra estructura de datos.

La solución utiliza la ventana deslizante / algoritmo de dos punteros. Tratemos de resolver el problema más simple primero:

  • Dada una matriz ordenada, encuentre todos los pares de elementos a, b de modo que a + b = c, un valor dado

Ahora, supongamos que hemos encontrado una solución ar [i], ar [j]. Es decir, ar [i] + ar [j] = c. Si hay alguna otra solución con ar [i ‘] (es decir, ar [i’] + ar [j ‘] = c), tendremos j’≤j. Usando esta observación, el problema puede resolverse mediante la siguiente función en O (N):

void findpairs(int ar[],int N,int c) { for(int i=0,j=N-1;ic) { j--; continue; } if(ar[i]+ar[j]==c)printf("%d %d\n",ar[i],ar[j]); i++; } } 

Ahora, si hay entradas duplicadas en la matriz, también podría haber entradas duplicadas en la salida. Esto se puede solucionar fácilmente con una simple modificación. Nos aseguramos de procesar los valores i correspondientes a un ar [i] dado solo una vez:

 void findpairs(int ar[],int N,int c) { for(int i=0,j=N-1;ic) { j--; continue; } if(ar[i]+ar[j]==c)printf("%d %d\n",ar[i],ar[j]); //Increment i till ar[i] is different from current value do { i++; }while((i 

Ahora para volver al problema original. Primero ordenaremos la matriz para utilizar el algoritmo de dos punteros. Primero arreglemos el elemento más pequeño en el triplete ar [i]. Ahora necesitamos encontrar otros elementos en la matriz de modo que su suma sea -ar [i]. Usando el mismo truco para evitar repeticiones, aquí está la solución final:

 void findtriplets(int ar[],int N) { //First sort the array since the method works only for sorted arrays sort(ar,ar+N); //Loop over first element of triplet for(int i=0;i0)&&(ar[i]==ar[i-1]))continue; //This loop is essentially the same as findpairs() above. for(int j=i+1,k=N-1;j0) { k--; continue; } if(ar[i]+ar[j]+ar[k]==0) { printf("%d %d %d\n",ar[i],ar[j],ar[k]); } do { j++; }while((j 

La clasificación lleva tiempo O (N log N) mientras que la aplicación repetida del algoritmo de dos punteros lleva tiempo O (N²).

Es solo una variación del problema de 3sum y Brian Schmitz dijo:
1. Ordenar la matriz
2. Arregle el primer elemento y encuentre otros dos basados ​​en la observación a continuación
a [x] + a [y] + a [z] = 0
a [x] = – (a [y] + a [z])
Por lo tanto, solo tenemos que averiguar si a [y] + a [z] es igual a a [x] o no.

Código simple de Python para ilustrar lo mismo.
def sum3 (a):
un tipo();
imprimir un
i = 0
para i en rango (0, len (a) -4):
x = i
y = i + 1
z = len (a) – 1
para j en el rango (1, len (a) -3):
si a [x] + a [y] + a [z] == 0:
imprime a [x], a [y], a [z]
y + = 1
z – = 1
elif a [x] + a [y] + a [z] <0:
y + = 1
más:
z – = 1

a = [-1, 0, 1, 2, -2, -3, -4]
imprimir sum3 (a)

Aunque Raziman ha descrito la idea básica, si alguien todavía quiere hacer más cosas, lea aquí, es un problema bien conocido de 3SUM, que puede resolverse en
como dice la página wiki.

  / * paquete lo que sea;  // ¡no coloques el nombre del paquete!  * /

 import java.util. *;
 import java.lang. *;
 import java.io. *;

 / * El nombre de la clase debe ser "Principal" solo si la clase es pública.  * /
 clase Ideone
 {
     public static void main (String [] args) arroja java.lang.Exception
     {
         int a [] = {-1, 0, 1, 2, -1, -4};
         find3s (a);
     }
    
     public static void find3s (int [] a) {
         Arreglos.sort (a);
         int N = a.length;
         para (int i = 0; i  0 && a [i] == a [i-1]) {continuar;}
            
             para (int j = i + 1, k = N-1; j  0) {
                     k--;
                     continuar;
                 }
                 if (a [i] + a [j] + a [k] == 0) {
                     System.out.println ("[" + a [i] + "] - [" + a [j] + "] - [" + a [k] + "]");
                 }
                 hacer{
                     j ++;
                 }
                 while (j 

Aquí está mi solución en Swift 3

Problema: dada una matriz de enteros distintos, cuántos enteros triples suman exactamente cero