trovare gli elementi k più piccoli nell'array in O (k)


12

Questa è una domanda interessante che ho trovato sul web. Dato un array contenente n numeri (senza informazioni su di essi), dovremmo preelaborare l'array in tempo lineare in modo da poter restituire i k elementi più piccoli nel tempo O (k), quando ci viene dato un numero 1 <= k <= n

Ho discusso questo problema con alcuni amici ma nessuno è riuscito a trovare una soluzione; Qualsiasi aiuto sarebbe apprezzato!

note rapide: -l'ordine dei k elementi più piccoli non è importante -gli elementi nell'array sono numeri, potrebbero essere numeri interi e potrebbero non essere (quindi nessun ordinamento radix) -il numero k non è noto nella fase di pre-elaborazione. la preelaborazione è O (n) tempo. la funzione (trova k elementi più piccoli) nel tempo O (k).


4
Che ne dici di usare un min-heap?
Shir,

1
Guarda il calcolo di k-skyband e top-k. L'articolo cs.sfu.ca/~jpei/publications/subsky_tkde07.pdf ha una bella recensione della letteratura correlata.
András Salamon,

1
Shir-Ho esaminato l'idea di heap min. tuttavia, per stampare i k numeri più piccoli nell'heap minimo è in O (klogn) e non O (k) come richiesto
Idan,

4
@idannik: Perché pensi che occorra per trovare i k elementi più piccoli in un min-heap? Ω(klogn)k
Kristoffer Arnsfelt Hansen,

8
Non credo sia a livello di ricerca. Sembra un incarico. Dove lo hai trovato?
Kaveh,

Risposte:


24

Elaborare in anticipo l'array di valori nel tempo O ( n ) :nO(n)

  • in
  • mentre i>2
    • Calcola la mediana di A [ 1 .. i ] nel tempo O ( i )mA[1..i]O(i)
    • partizione in A [ 1 .. i / 2 - 1 ] m e A [ i / 2 + 1 .. i ] m contemporaneamente.A[1..i]A[1..i/21]mA[i/2+1..i]m
    • ii/2

Il tempo totale precomputation è a O(1+2+4+...+n)O(n)

Rispondi a una query per i elementi più piccoli in A nel tempo O ( k ) :kAO(k)

  • llog2k
  • seleziona il th elemento x di A [ 2 l . .2 l + 1 ] nel tempo O ( 2 l ) O ( k )(k2l)xA[2l..2l+1]O(2l)O(k)
  • partizione di x contemporaneamenteA[2l..2l+1]x

contiene i k elementi più piccoli.A[1..k]k

Riferimenti:

  • Nel 1999, Dor e Zwick hanno dato un algoritmo per calcolare la media di elementi nel tempo all'interno 2.942 n + O ( n ) confronti, che produce un algoritmo per selezionare il k -esimo elemento di n elementi non ordinati in meno di 6 n confronti.n2.942n+o(n)kn6n

1
Immagino che il ciclo esterno dovrebbe essere "for i in ". Il tuo algoritmo è diverso da quello nella risposta di Yuval Filmus? {2lgn,,4,2,1}
Radu GRIGore,

2
Questa è una generalizzazione del mio algoritmo a arbitrario . Spiega anche alcuni dettagli di implementazione che sono stati (deliberatamente) esclusi dalla mia risposta. n
Yuval Filmus,

3
@YuvalFilmus Vuoi implicare con il tuo commento che la mia risposta non è eticamente vicina alla tua? Questa è la soluzione che mi è venuta in mente quando ho esaminato la domanda. Ho visto che ne hai pubblicato uno simile, ma l'ho trovato poco chiaro, quindi ho scritto il mio (invece di fare una tua modifica importante). Ciò che conta alla fine è la qualità delle risposte sui sistemi, non proprio chi li ha scritti: i badge e la reputazione sono solo incentivi, non obiettivi in ​​sé.
Jeremy,

4
@Jeremy Per niente; Solo che le due soluzioni sono uguali (ma la tua funziona per arbitrarie ) e che non ho perfezionato i dettagli nel caso in cui fosse effettivamente una domanda per i compiti. n
Yuval Filmus,

2
Oh :( Mi dispiace per quello. (Anche se penserei ancora che dare risposte complete sia una priorità rispetto ai sospetti di incarico)
Jeremy

14

n=2m2m1,2m2,2m3,,1kt2t1k2t2t2k2tkO(2t)=O(k)

Θ(nlogn)

while n > 0:
  find the (lower) median m of A[0..n-1]
  partition A in-place so that A[n/2-1] = m
  n = n/2

n+n/2+n/4++1<2nAkA[0..n/2k1]n/2k


1
O(1)kO(n)

4
lognnlogn

3
@ AndrásSalamon: se leggi la risposta data da Jeremy (che mi sembra quasi la stessa di questa) vedi che prima elabori l'intero array, quindi la prima metà e così via.
Radu GRIGore,

3
n+n/2+n/4++1<2n

5
Per inciso, questo algoritmo appare come una subroutine nella mia risposta a una domanda precedente: cstheory.stackexchange.com/questions/17378/…
David Eppstein,


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.