Come sviluppare un algoritmo risolvere il problema della somma 2?


8

Dato un array ordinato di numeri interi, voglio trovare il numero di coppie che si sommano a . Ad esempio, dato \ {- 3, -2,0,2,3,4 \} , il numero di coppie somma a zero è 2 .0{3,2,0,2,3,4}2

Sia N il numero di elementi nella matrice di input. Se uso la ricerca binaria per trovare l'inverso dell'additivo per un elemento nella matrice, l'ordine è O(logN) . Se attraverso tutti gli elementi nel set, allora l'ordine è O(NlogN) .

Come trovare un algoritmo di ordine O(N) ?


2
Il problema k -SUM di solito si riferisce a un problema leggermente diverso, in cui si cerca di trovare un set di k elementi dall'array di input A tale che si sommino a zero. In un certo modello di calcolo, è impossibile ottenere un algoritmo di tempo lineare per k=2 o per qualsiasi k . Vedere questa domanda .
Juho,

Risposte:


12

Sia l'array di input ordinato. Mantenere due puntatori e che passano attraverso gli elementi in . Il puntatore passerà attraverso la "parte sinistra" di , ovvero gli interi negativi. Il puntatore fa lo stesso per la "parte destra", gli interi positivi. Di seguito, descriverò una soluzione di pseudocodice e presumo che per minore semplicità. Omesso sono anche i controlli per i casi in cui ci sono solo positivo o solo numeri interi negativi in .AlrAlAr0AA

COUNT-PAIRS(A[1..N]):
 l = index of the last negative integer in A
 r = index of the first positive integer in A
 count = 0;

 while(l >= 0 and r <= N)
   if(A[l] + A[r] == 0)
     ++count; ++right; --left; continue;

   if(A[r] > -1 * A[l]) 
     --left;
   else 
     ++right;

È ovvio che l'algoritmo richiede tempo .O(N)


3
Probabilmente dovresti aggiungere un argomento per la correttezza.
Raffaello

-1

L'approccio più semplice, secondo la mia comprensione, sembra essere l'uso di una tabella hash, H = {a [0] = true, .., a [n-1] = true}. Questa tabella hash può essere costruita in tempo O (n). Una volta creata la tabella hash, scorrere tra A [0, .., n-1] e verificare se esiste H [-1 * a [i]]. In tal caso, incrementa un contatore di 1 e restituisce il risultato finale. Questo è chiaramente O (n).


3
Le espressioni H = {a [0] = true, .., a [n-1] = true} e A [0, .., n-1] non hanno alcun senso per me. Quando si utilizza una funzione hash, l'array non deve nemmeno essere ordinato. Ma gli algoritmi che usano la funzione hash usano alcune proprietà pseudocasuali della funzione hash. Nel peggiore dei casi tutti gli elementi verranno mappati allo stesso valore di hash e l'algoritmo è quadratico. Non so quali sono i requisiti del PO.
miracle173

Vedi la mia implementazione di questo sotto e dimmi come è quadratico nel peggiore dei casi.
Sammy,

@ miracle173: questa è solo comodità per la notazione. Posso rappresentare la tabella hash come un insieme di coppie chiave-valore (che è quello che è in realtà, matematicamente parlando). L'effettiva disposizione in memoria non è necessaria per dettagli teorici sulla complessità. Inoltre, le funzioni di hash sono progettate per evitare collisioni a condizione che entropia da seme sia sufficiente. Ho risposto con il perché la risposta di Juho assume una "A ordinata", che implica implicitamente la complessità O (n log (n)) e * NOT O (n).
Juspreet Sandhu,

@ manbearpig1 User Evil ha già aggiunto un commento al tuo post che dovrebbe rispondere alla tua domanda. Il caso peggiore della ricerca della tabella hash è O (n) e quindi il caso peggiore dell'intero algoritmo è O (n ^ 2).
miracle173,

@JuspreetSandhu Usere Il male ha aggiunto un commento ad un'altra risposta che spiegava il problema con le funzioni hash.
miracle173,

-1

Nota che possiamo cercare un valore in un set Python in tempo costante.

def twoSum(data):
    count = 0
    nums = set()
    for num in data:
        if (num * -1) in nums:
            count += 1
        nums.add(num)
    return count

1
Non è tempo costante ma tempo costante previsto. Potrebbe esserci una tabella hash, un albero (auto) bilanciato o una struttura simile. Ciò fornisce previsto ma potrebbe essere in caso degradato per la tabella hash o per l'albero. Inoltre qui preferiamo lo pseudocodice perché non tutti capiscono il pitone, quindi non è chiaro perché o come funzioni. Nel peggiore dei casi per la tabella hash in cui ogni valore è mappato in un bin, il tempo per ottenere l'elemento è . Esegui questo passaggio volte in modo da dare nel peggiore dei casi. O(1)O(n)O(logn)O(n)nO(n2)
Evil
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.