2011-02-09 23 views
5

Dato un elenco collegato di numeri interi in ordine casuale, suddividerlo in due nuovi elenchi collegati in modo tale che la differenza nella somma degli elementi di ciascuna lista sia massima e la lunghezza degli elenchi differisce di non più di 1 (nel caso in cui l'elenco originale abbia un numero dispari di elementi). Non posso presumere che i numeri nella lista siano unici.dividere un elenco collegato in 2 liste pari contenenti i numeri più piccoli e più grandi

L'algoritmo ho pensato è stato quello di fare un merge sort sulla lista collegata originale (O (n & middot; log n) tempo, O (n) spazio) e quindi utilizzare una funzione ricorsiva per raggiungere a piedi la fine della lista per determinare la sua lunghezza, facendo la divisione mentre la funzione ricorsiva si srotola. La funzione ricorsiva è O (n) e lo spazio O (n).

Questa è la soluzione ottimale? Posso pubblicare il mio codice se qualcuno pensa che sia rilevante.

+0

Se tuo l'implementazione della lista collegata mantiene una proprietà di dimensione, quindi devi solo camminare a metà dell'elenco per tagliarlo a metà. (Potrebbe voler dare un'occhiata a http://codereview.stackexchange.com!) – Jeremy

+0

@Jeremy Heiler: Nessuna proprietà di dimensione, solo una semplice lista di link semplice di jane, in realtà niente più di un mucchio di nodi collegati tra loro. –

+0

A meno che l'esame non richieda di implementare l'ordinamento, è possibile utilizzare anche Collections.sort per eseguire l'ordinamento. – karakuricoder

risposta

4

No, non è ottimale; potete trovare lo median of a list in O(n), quindi inserirne la metà in una lista (minore della mediana o uguale, fino alla dimensione della lista essere n/2) e metà di quella in un'altra lista ((n + 1)/2). La loro differenza somma viene massimizzata, e non v'è alcuna necessità di ordinare (O (n & middot;. Log (n)) Tutte le cose saranno fatte in O (n) (spazio e tempo)

+0

Il collegamento che hai fornito sembra indicare che questo algoritmo è adatto agli array ad accesso casuale. Sei sicuro che funzioni per le liste collegate? –

+0

@Robert S. Barnes: Se necessario, potremmo copiare l'elenco prima in un array e poi indietro, sempre O (n). –

+0

Un'altra cosa, basata su questa analisi http://www.soe.ucsc.edu/classes/cmps102/Spring05/selectAnalysis.pdf dell'algoritmo Median of Medians, richiede che gli elementi dell'array siano unici. Non posso supporre quello. –

1

Perché. hai bisogno di una funzione ricorsiva? Mentre leggi l'elenco di ordinamento, puoi contare gli elementi, quindi dividili a metà.Questo elimina il fabbisogno di spazio O. n.

Anche se non è possibile contare la lunghezza dell'elenco durante l'ordinamento, è comunque possibile essere diviso in O (n) tempo e O (1) spazio: ottenere due elenchi di iteratori all'inizio, avanzare i primi 2 elementi per ogni passaggio, secondo 1 elemento per ogni passo Quando si raggiunge per la prima volta l'elenco - tagliare al secondo

+0

I sto già dividendo nel tempo O (n). Prende O (n) spazio perché sto facendo delle copie dell'originale LL. –

Problemi correlati