2013-08-10 7 views
5

Viene fornita una serie di intervalli S. È necessario trovare tutti gli intervalli in S contenuti in un dato intervallo (a, b) con una complessità temporale minima.Viene fornita una serie di intervalli S. È necessario trovare tutti gli intervalli in S che sono contenuti in un dato intervallo (a, b) in una complessità temporale minima

Questo può essere fatto in O(n) tempo con la forza bruta, in cui n è il numero di intervalli in serie S. Ma se mi è permesso fare qualche pre-elaborazione, questo può essere fatto in meno di tempo O(n) ad es. O(log n) tempo?

Inizialmente pensavo interval tree, ma non credo che essa è applicabile qui perché albero intervallo viene utilizzata per ottenere tutti gli intervalli che si sovrappone con un dato intervallo.

+0

Come detto, il meglio che puoi fare è 'O (n)', perché, nel peggiore dei casi, tutti gli elementi del 'S' deve essere copiato all'uscita. –

+0

Sì, è vero. Ma speravo in qualcosa tipo O (logn) + O (m), dove m è il numero di elementi nell'output. –

+0

@SteveM nota bene che, in termini di notazione O grande, 'O (logn) + O (m) = O (n)', perché m può essere grande come n. Anche il tempo di elaborazione preliminare è incluso nel runtime, perché se si desidera ordinare gli intervalli o organizzarli utilizzando alcune strutture di dati, anche questi fanno parte dell'algoritmo. – Fallen

risposta

5

È possibile rimodellare il problema sul piano 2D. Lascia che il (begin, end) di ogni intervallo sia un punto bidimensionale. (Si noti che tutti gli intervalli validi finiranno sopra la diagonale)

l'intervallo di-ricerca-problema si trasforma in gamma 2D ortogonale ben studiato query con algoritmi che hanno O(sqrt(n)+k) o O(log^2+n +k) runtime, dove k è il numero di punti segnalati.

range query

+0

Bella idea, ma non sono a conoscenza di alcun algoritmo con una complessità inferiore a O (k) dove k è il numero di punti riportati. Quindi, Patricia ha ragione. – Matthias

+0

Sì, è vero. Ho aggiornato la mia risposta per includere la descrizione di k. Ma a volte i punti dati sono ben distribuiti e le tue query coprono solo un piccolo insieme, in modo da ammortizzare k << n. –

1

Persistent binary search tree può essere utilizzato qui.

pre-processing:

  1. Creare albero persistente vuoto. Dovrebbe memorizzare gli intervalli ordinati per i loro punti finali.
  2. Ordinamento degli intervalli in base al loro punto di partenza.
  3. Per ciascun intervallo, a partire dalla fine dell'elenco ordinato, creare una "copia" dell'albero persistente e aggiungere questo intervallo a questa copia.

Ricerca:

  1. trovare il punto dell'intervallo query nella lista ordinata di partenza.
  2. Iterare la "copia" corrispondente dell'albero persistente dalla chiave più piccola alla fine dell'intervallo della query.

La complessità del tempo di ricerca è O (log (n) + m), dove m è il numero di elementi nell'output.

+0

Sembra che la sua complessità spaziale sia O (n^2). Perfavore, correggimi se sbaglio. –

+0

@SteveM: la complessità dello spazio è O (n * log (n)). Strutture di dati persistenti consentono di creare "copie" poco profonde in cui la maggior parte dei dati è condivisa tra "copie", quindi ogni aggiornamento BST necessita solo di O (log (n)) nodi aggiuntivi. –

Problemi correlati