Given an array A of length n and a bound k find all indices
(i,j) such that A[i] + A[j] < k.
Questo può essere risolto in O (n log n) .
Il set I di indici (i, j) che stai cercando ha una struttura
quando la matrice è ordinata in ordine crescente. Infatti se (i₀, j₀)
appartiene a I quindi, ogni volta che i ≤ i₀ e j ≤ j₀ la coppia indice
(i, j) appartiene anche a I . Ciò significa che I assomiglia a questo:
...........
++*........
+++........
+++........
+++........
+++........
+++++*.....
++++++.....
++++++++*..
+++++++++..
dove un punto .
denota una coppia che non appartiene a I mentre un
più +
o una stella *
denota una coppia appartenente a I . Come vedi,
la presenza di un indice denotato +
è implicata dalla presenza di
un indice denotato da una stella *
quindi solo quest'ultimo deve essere
cercato.
-
Ordina l'array in O (n log n)
-
Imposta i sull'indice più grande in modo che A [i] ≤ k in O (n) e impostare
j a 1 se usi Pascal o 0 se usi un'altra lingua, questo
Quest'ultima operazione è O (1) .
-
Se A [i] + A [j] è maggiore di k quindi diminuisci i e prova 3.
di nuovo, altrimenti vai al 4.
-
Se A [i] + A [j + 1] è più piccolo di k quindi aumenta j e prova 4. ancora una volta.
-
Abbiamo trovato un punto contrassegnato con *
aggiungilo a I e diminuisci
i .
-
Se A [i] + A [j + 1] è maggiore di k quindi diminuisci i e prova 6. ancora una volta.
-
Vai a 4.
Non dimenticare di correggere l'algoritmo e aggiungere il controllo dei limiti e
condizioni di uscita adeguate. Nella parte ripetitiva 3.-7. l'algoritmo
visita solo gli indici che si trovano alla frontiera tra I e il suo
complemento. Questa frontiera ha al massimo 2n quindi il costo complessivo
di questa esplorazione è O (n) . La parte ripetitiva 3.-7. è solo un modo ingegnoso per dire: visita quella frontiera, ricordando ogni volta che devi cambiare direzione.
Il costo totale dell'algoritmo è quindi O (n log n) + O (n) + O (1) +
O (n) = O (n log n) .
P.S .: In realtà l'immagine dovrebbe essere simmetrica attorno alla prima diagonale e l'algoritmo può smettere di esplorare la frontiera quando incontra la diagonale. Questi sono piccoli dettagli.
P.P.S .: Ovviamente, se la tua condizione non ha una struttura, devi esplorare tutte le combinazioni.