Scambio tempo-spazio per problema elemento mancante


14

Ecco un problema ben noto.

Dato un array di numeri interi positivi, genera il numero intero positivo più piccolo non presente nell'array.A[1n]

Il problema può essere risolto nello spazio e nel tempo : leggere l'array, tenere traccia nello spazio indipendentemente dal fatto che si siano verificati , cercare l'elemento più piccolo.O(n)O(n)1,2,,n+1

Ho notato che puoi scambiare spazio con il tempo. Se hai O(nk)solo memoria, puoi farlo inround e ottenere il tempo. In un caso speciale, esiste ovviamente un algoritmo a tempo quadratico a spazio costante.kO(kn)

La mia domanda è:

È questo il compromesso ottimale, ovvero ? In generale, come si dimostra questo tipo di limiti?timespace=Ω(n2)

Assumi il modello RAM, con aritmetica limitata e accesso casuale agli array in O (1).

Ispirazione per questo problema: compromesso spazio-tempo per i palindromi nel modello a nastro singolo (vedi ad esempio qui ).


2
No, potresti ordinare il tuo array in O(nlogn) quindi trovare il numero mancante (il primo numero dovrebbe essere 1, il secondo dovrebbe essere 2, ... altrimenti lo troverai) in O (n), questo ordinamento potrebbe essere fatto con inplace mergesort, significa O(1) spazio extra, quindi il tempo spazio appartiene a O(nlogn) . Non so di avere il tuo problema esattamente o no (per questo non ho risposto, inoltre non so se esiste un limite migliore).

Presumo che l'input sia di sola lettura. (In caso contrario, il problema può essere risolto in modo ottimale nello spazio / O ( 1 ) : moltiplica l'input per 2 e usa la parità per simulare l' algoritmo O ( n ) / O ( n ) )O(n)O(1)O(n)/O(n)
sdcvvc

Qual è l'algoritmo dello spazio costante? Sembra che avresti bisogno di spazio per la versione n 2 che è "ovvia" per melognn2
Xodarap

In questo modello, numeri interi di dimensioni di parole prendono ; se è più conveniente, puoi rispondere a qualsiasi variante della domanda con il tempo spazio = Ω ( n 2O(1)per qualche costantek. timespace=Ω(n2logkn)k
sdcvvc,

@sdcvvc, non riesco a capire il tuo algoritmo , lo descriveresti un po 'di più? (basta notare che la lettura in bit richiede O ( log n ) ). O(n)/O(1)O(logn)

Risposte:


2

Questo può essere fatto in operazioni a parola O(nlogn) e parole di memoria O(1) (rispettivamente tempo O(nlog2n) e memoria O(logn) nel modello RAM a livello di bit). In effetti, la soluzione si baserà sulla seguente osservazione.

Supponiamo che ci siano n0 numeri pari e n1 numeri dispari nell'intervallo [1,n+1] (quindi n0n1 e n0+n1=n+1 ). Quindi c'è b{0,1} tale che ci sono al massimo nb1 valori con parità b nell'input. Anzi, altrimenti ci sono almeno n0pari e almeno n1 valori dispari nell'input, il che significa che ci sono almeno n0+n1=n+1 valori nell'input, contraddizione (ce ne sono solo n ). Significa che possiamo continuare a cercare il numero mancante solo tra i numeri pari o dispari. Lo stesso algoritmo può essere applicato anche a bit più alti di notazione binaria.

Quindi il nostro algoritmo sarà simile a questo:

  1. Supponiamo che già ora ci siano solo x valori nell'input con il resto modulo 2b uguale a r[0,2b) ma ci sono almeno x+1 numeri nell'intervallo [1,n+1] che hanno resto r modulo 2b (all'inizio sappiamo che per b=0,r=0 ).

  2. Supponiamo che ci siano x0 valori nell'input con resto r modulo 2b+1 e x1 valori nell'input con resto r+2b modulo 2b+1 (possiamo trovare questi numeri in un singolo passaggio attraverso l'ingresso). Chiaramente, x0+x1=x . Inoltre, poiché ci sono almeno x+1 numeri nell'input con resto r modulo 2b , almeno una delle coppie(r,b+1),(r+2b,b+1) soddisfa i requisiti del passaggio1 .

  3. Abbiamo trovato il numero mancante quando 2bn+1 : c'è un solo numero nell'intervallo [1,n+1] che può avere resto r modulo 2b ( r stesso se è nell'intervallo), quindi ci sono maggior parte dei valori zero nell'input che hanno tale resto. Quindi manca davvero r .

Chiaramente, l'algoritmo si interrompe nei passaggi O(logn) , ognuno di essi richiede tempo O(n) (passaggio singolo sull'array di input). Inoltre, sono necessarie solo O(1) parole di memoria.


Sono felice di vedere la risposta alla domanda dopo quel momento :)
sdcvvc,

1

Se capisco le tue definizioni, questo può essere fatto in tempo lineare con spazio costante. Questo è ovviamente il limite più basso, perché dobbiamo almeno leggere l'intero input.

La risposta fornita in questa domanda è soddisfacente.

È impossibile eseguirlo con meno tempo o spazio e l'aggiunta di tempo o spazio extra è inutile, quindi non c'è compromesso spazio-tempo qui. (Osserva che , quindi il compromesso che hai osservato non si mantiene asintoticamente, in ogni caso.)n=O(n/k)

Per quanto riguarda la tua domanda generale, non conosco i teoremi simpatici che ti aiuteranno a dimostrare i compromessi spazio-temporali. Questa domanda sembra indicare che non esiste una risposta (nota) facile. Fondamentalmente:

Supponiamo che una certa lingua sia decidibile in tempo (usando una certa quantità di spazio) e s spazio (usando una certa quantità di tempo). Possiamo trovare f , g tale che L sia decidibile per M che corre nello spazio f ( t , s ) e nello spazio g ( t , s ) ?tsf,gLMf(t,s)g(t,s)

è sconosciuto, e una risposta forte risolverebbe molti problemi aperti (in particolare su SC), il che implica che non esiste una soluzione facile.


EDIT: Ok, con ripetizione (ma sto ancora supponendo che con un input di dimensione il numero massimo possibile sia n + 1 ).nn+1

Osserva che il nostro algoritmo deve essere in grado di distinguere tra almeno possibili risposte. Supponiamo che ad ogni passaggio attraverso i dati possiamo ottenere al massimo k pezzi di dati. Quindi avremo bisogno di n / k pass per differenziare tutte le risposte. Supponendo che k = n / s corriamo in nnkn/kk=n/stempo. Quindi penso che questo provi quello che vuoi.nn/sn=sn

La difficoltà sta nel mostrare che ogni volta che otteniamo solo bit. Se supponi che la nostra unica operazione legale sia =, allora siamo a posto. Tuttavia, se consenti operazioni più complesse, sarai in grado di ottenere maggiori informazioni.k


3
La domanda che hai collegato presuppone che ogni numero appaia al massimo una volta. Non faccio questo presupposto, quindi la soluzione non si applica. Grazie per il secondo link.
sdcvvc,

@sdcvvc: errore mio, ho pensato che stavi usando la versione che conosco. Non ho una risposta completa, ma è troppo lungo per un commento - spero che la mia modifica sia utile.
Xodarap,

5
Non compro il tuo argomento dopo "EDIT". Anche se puoi raccogliere bit in un solo passaggio, in linea di principio è sufficiente distinguere 2 k possibili output. Quindi questo argomento può implicare solo un limite inferiore di n / 2 k passaggi, non n / k . k 2kn/2kn/k
JeffE,
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.