2012-06-10 15 views
5
Find the nth most frequent number in array. 
(There is no limit on the range of the numbers) 

Penso che possiamoTrovare il numero N-esimo più frequente nella matrice

(i) memorizzare il verificarsi di ogni elemento utilizzando le mappe in C++

(ii) costruire un Max-heap nel tempo lineare delle occorrenze (o frequenza) dell'elemento e quindi estrae fino all'elemento N-esimo, Ogni estrazione richiede log (n) il tempo di heapify.

(iii) avremo la frequenza del N-esimo numero più frequente

(iv) allora possiamo lineare ricerca tra l'hash per trovare l'elemento avente questa frequenza.

Tempo - O (N log N) Space - O (N)

Esiste un metodo migliore?

+1

Sede [Algoritmo Selezione] (http://en.wikipedia.org/wiki/ Selection_algorithm) che consente di selezionare l'elemento Nth dall'array non ordinato in O (N). – salva

+1

@salva - La domanda è selezionare l'n-esimo numero di FREQUENZA e non l'ennesimo elemento. – user754657

+0

@ user754657: sì, il passaggio * i * è ancora richiesto, ma i passaggi * ii *, * iii * e * iv * possono essere sostituiti dall'algoritmo di selezione che è O (N), risultante in una soluzione che è O (N) a livello globale. – salva

risposta

3

Il tuo metodo è fondamentalmente corretto. Eviterai la ricerca di hash finale se contrassegni ciascun vertice dell'heap costruito con il numero che rappresenta. Inoltre, è possibile tenere costantemente sotto osservazione il quinto elemento del mucchio mentre lo si sta costruendo, perché a un certo punto si può arrivare a una situazione in cui il risultato non può più cambiare e il resto del calcolo può essere eliminato. Ma questo probabilmente non renderebbe l'algoritmo più veloce nel caso generale, e forse nemmeno in casi particolari. Quindi hai risposto correttamente alla tua domanda.

1

Dipende dal metodo più efficace o più facile da scrivere.

1) se si sa che tutti i numeri saranno compresi tra 0 e 1000, basta creare una serie di 1000 zeri (occorrenze), scorrere l'array e incrementare la posizione di occorrenza corretta. Quindi ordinate queste occorrenze e selezionate il valore Nth.

2) Hai una "borsa" di articoli unici, fai un giro tra i numeri, controlla se quel numero è in una borsa, in caso contrario, lo aggiungi, se è qui, basta incrementare il numero di occorrenze . Quindi scegli un n ° numero più piccolo da esso.

Borsa può essere array lineare, BST o Dizionario (tabella hash).

La domanda è "N-esimo più frequente", quindi penso che non è possibile evitare l'ordinamento (o la struttura dei dati intelligente), quindi la migliore complessità non può essere migliore di O (n * log (n)).

+0

Il metodo 1 non è realmente applicabile, poiché l'intervallo di numeri non ha un limite. Nel metodo 2, la selezione dell'ennesima più piccola può essere eseguita in termini di complessità di tempo medio O (K) (dove K è il numero di elementi unici) con algoritmo di selezione: la funzione 'nth_element' di STL' algorithm'. Il "sacco" può essere 'map' da STL come l'OP ha menzionato (STL' map' è migliore del normale BST, dato che 'map' è implementato come albero auto-bilanciato). – nhahtdh

+0

nhahtdh: Non è possibile selezionare il N ° più piccolo tra i numeri K in O (K). Devi almeno ordinarli o scorrerli attraverso l'heap N-item ... che è la "borsa" di cui stavo parlando. –

+0

Se si cerca solo "nesimo elemento" o "algoritmo di selezione", vedrete cosa intendo. – nhahtdh

8

Può essere eseguito in tempo e spazio lineari. Sia T il numero totale di elementi nell'array di input da cui dobbiamo trovare il numero N ° più frequente:

  1. Contare e memorizzare la frequenza di ogni numero in T in una mappa. Sia M il numero totale di elementi distinti nella matrice. Quindi, la dimensione della mappa è M. - O (T)
  2. Trova l'ennesima frequenza nella mappa utilizzando Selection algorithm. - O (M)

Tempo totale = O (T) + O (M) = O (T)

Problemi correlati