Determinazione del numero particolare in tempo e spazio (caso peggiore)


10

Dato che A[1..n] sono numeri interi tali che 0A[k]m per tutto 1kn e il verificarsi di ciascuno numero tranne un numero particolare in A[1..n] è un numero dispari. Prova a trovare il numero la cui occorrenza è un numero pari.

Esiste un algoritmo Θ(nlogn) : A[1..n] in B[1..n] e suddividiamo B[1..n] in molti pezzi, il cui valore degli elementi è il lo stesso, quindi possiamo contare l'occorrenza di ciascun elemento.

Voglio trovare un algoritmo di spazio O(n) -time-e- O (n) nel caso peggiore O(n).

Supponendo che m=Ω(n1+ϵ) e ϵ>0 , quindi l'ordinamento radix non è accettabile. Le operazioni binarie bit a bit sono accettabili, ad esempio A[1]xorA[2] .


La risposta di Aryabhata che segue mostra che il caso generale non è buono, ma forse hai ulteriori restrizioni disponibili? Una semplice (ma grande) limitazione sarebbe quella di imporre che tutte le voci nell'array abbiano dimensioni O(n) . Ciò darebbe un algoritmo lineare piuttosto banale.
Luke Mathieson,

1
@LukeMathieson: ho eliminato quella risposta, poiché non sono ancora convinto che il documento che ho citato funzionerà senza alcuna modifica, e inoltre, OP sembra interessarsi solo al modello di RAM a costo uniforme.
Aryabhata,

@Aryabhata: hehe, beh la risposta che non c'è allora! Per quanto interessante e forse utile per Frank, quale pensavi fosse il problema di adattare il risultato nel documento? Un rapido suggerimento suggerì che fosse applicato, ma ovviamente non avevo letto.
Luke Mathieson,

@LukeMathieson: il fatto che gli altri elementi debbano apparire un numero dispari di volte nel problema attuale. Da allora, ho sfiorato anche la prova ...
Aryabhata,

Sarebbe interessante se sei interessato a risultati teorici o a soluzioni pratiche. Dal punto di vista della teoria, la mia prima risposta rapida è che puoi ordinare un elenco di numeri interi più velocemente di . Esiste un algoritmo deterministico di Han che viene eseguito nel tempo . Per gli algoritmi randomizzati, sono noti risultati ancora migliori, ad esempio Han e Thorup hanno trovato un algoritmo di tempo previsto . Tuttavia, penso che il tuo problema non dovrebbe richiedere l'ordinamento. O(nlogn)O(loglogn)O(nloglogn)
A.Schulz,

Risposte:


2

Ecco un'idea per un semplice algoritmo; conta solo tutte le occorrenze!

  1. Trova . - timem=maxAΘ(n)
  2. Matrice "Allocate" . - tempo ¹C[0..m]O(1)
  3. Scorri su e aumenta di uno ogni volta che trovi . Se è , aggiungere ad una lista lineare . - timeAC[x]A[_]=xC[x]0xLΘ(n)
  4. Scorrere su e trovare l'elemento con pari. - tempo .LxeC[xe]O(n)
  5. Ritorna .xe

Tutto sommato, questo ti dà un algoritmo a tempo lineare che può usare (nel senso di allocare) molta memoria. Si noti che la possibilità di accedere casualmente a in tempo costante indipendentemente da è cruciale qui.Cm

Un ulteriore legato allo spazio è più difficile con questo approccio; Non conosco alcuna struttura di dati del dizionario che offra una ricerca temporale . Puoi usare le tabelle hash per le quali qui sono implementazioni con tempo di ricerca previsto ( la dimensione della tabella, il numero di elementi memorizzati) in modo da poter ottenere arbitrariamente bene con lo spazio lineare - nell'aspettativa. Se tutti i valori in mappa hanno lo stesso valore hash, sei fregato.O(n)O(1)O(1+k/n) nkA


  1. Su una RAM, questo è implicitamente fatto; tutto ciò di cui abbiamo bisogno è la posizione iniziale e forse la posizione finale.

0

Una soluzione quasi banale - che utilizza comunque lo spazio - è usare una mappa hash. Ricordiamo che una mappa hash ha ammortizzato il runtime per l'aggiunta e la ricerca di elementi.Θ(n)O(1)

Quindi, possiamo usare il seguente algoritmo:

  1. Allocare un hash mappa . Iterare su . Per ogni elemento , aumenta il numero di occorrenze osservate, ovvero .HAiAH(i)++

  2. Scorrere il set di chiavi della mappa hash e verificare quale delle chiavi ha un conteggio uniforme delle occorrenze.

Ora questo è un semplice algoritmo che in realtà non usa alcun trucco di grandi dimensioni, ma a volte anche questo è sufficiente. In caso contrario, potresti voler specificare quali restrizioni di spazio imponi.


Vorrei ancora sapere se esiste un algoritmo non randomizzato che utilizza lo spazio polinomiale. In particolare, ci sono prove teoriche che trovare il solo oggetto che si verifica in modo equo sia più difficile che trovare l'unico oggetto che si presenta in modo strano? O(n)
A.Schulz,

@ A.Schulz Penso che sia l' algoritmo -expected-time utilizzando la tabella hash. Ricordo che qualcuno mi ha detto un algoritmo (o per un caso speciale, diciamo, dispari = 1 e persino = 2) forse con stack, ma non riesco a ricordarlo. O(n)O(n)
Yai0Phah,

Non tutte le implementazioni hashtable hanno questa proprietà; di solito, la ricerca non è , nemmeno ammortizzata (afaik). In effetti, una discussione precedente non ha prodotto alcuna implementazione con una ricerca temporale costante. Può essere più preciso? O(1)
Raffaello
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.