Riassegniamo il problema: dobbiamo trovare due elementi, ad esempio abs(x-y) <= c
, dove c
è una costante, che possiamo trovare nel tempo O(n)
. (In effetti, possiamo calcolare sia max(A)
e min(A)
in tempo lineare e basta assegnare c=(max-min)/n
).
Immaginiamo abbiamo una serie di segmenti, in modo che in primi elementi di benna 0<=x<c
verranno effettuati nei secondi elementi benna c<=x<=2c
immessi, ecc Per ogni elemento, possiamo determinare il suo secchio per O(1)
tempo. Si noti che il numero di bucket occupati non sarà superiore al numero di elementi nella matrice.
Andiamo a ripetere l'array e posizionare ciascun elemento nel suo bucket. Se nel bucket lo inseriremo, esiste già un altro elemento, quindi abbiamo appena trovato la coppia corretta di x
e !
Se abbiamo iterato l'intero array e ogni elemento è caduto nel suo stesso secchio, nessuna preoccupazione! Iterate i bucket ora (non ci sono più di n
bucket, come abbiamo detto sopra) e per ogni elemento bucket x
, se nel prossimo bucket elemento è tale che abs(x-y)<=c
, quindi abbiamo trovato la soluzione.
Se abbiamo ripetuto tutti i bucket e non abbiamo trovato elementi corretti, non c'è soluzione.
OMG, mi sono davvero perso quella roba da piccionaia (vedi the other answer).
I bucket possono essere implementati come una mappa hash, in cui ciascun bucket contiene un indice di array (l'elemento di posizionamento nel bucket sarà simile al seguente: buckets[ a[i]/c] = i
). Calcoliamo c
nell'orario O(n)
, assegna gli elementi ai bucket nel tempo O(n)*O(1)
(O(1)
è l'accesso alla mappa hash), attraversa i bucket nel tempo O(n)
. Pertanto, l'intero algoritmo è lineare.
fonte
2009-11-21 20:11:30
Interessante e molto diverso dalla maggior parte delle domande dei compiti qui. Anche se anch'io non riesco a trovare un'idea :-( – Joey
Ci sono duplicati nell'array e sono i valori sparsi o densi? –