def f(l):z=zip(l,range(len(l)));print map(sorted(z).index,z)
Provalo online!
Utilizza l'indicizzazione zero.
Un algoritmo veloce con un'idea semplice. Se invece necessario permutare lista di input per renderlo il più vicino a (1,2,...,n) come possibile, dovremmo appena sorta, come dimostrato qui sotto. Dal momento che stiamo invece permutando (1,2,...,n) , abbiamo scelto la permutazione di quel ordinato allo stesso modo come la lista di input, come nel mio sfida Imitare un ordinamento (tranne l'ingresso può avere ripetizioni). (Modifica: miglia ha sottolineato questa sfida più identica , in cui Dennis ha la stessa risposta .)
Modifica: Una permutazione dell'elenco l che minimizza la sua distanza (1,2,...,n) è l ordinati.
Prova: considera qualche altra permutazione l′ di l . Dimostreremo che non può essere migliore di quello che l ordinato.
Scegli due indici i,j che l′ ha fuori servizio, ecco dove i<j ma l′i>l′j . Abbiamo dimostrato che scambiando loro non può aumentare la distanza (1,2,...,n) . Notiamo che lo swap modifica il contributo di questi due elementi come segue:
|l′i−i|+|l′j−j|→|l′i−j|+|l′j−i|.
Ecco un modo accurato per dimostrare che questo non può essere un aumento. Consideriamo due persone che camminano su una linea numerica, una che va da l′i per i e l'altro da l′j a j . La distanza totale che percorrono è l'espressione a sinistra. Poiché i<j ma l′i>l′j , cambiano chi è più in alto sulla linea numerica, il che significa che devono attraversare ad un certo punto durante le loro passeggiate, chiamarlo p . Ma quando raggiungono p, potrebbero quindi scambiare le loro destinazioni e percorrere la stessa distanza totale. E poi, non può essere peggio per loro aver camminato verso le loro destinazioni scambiate dall'inizio piuttosto che usare p come waypoint, che fornisce la distanza totale sul lato destro.
Quindi, smistamento due elementi out-of-ordinare l′ rende la sua distanza (1,2,...,n) minore o uguale. Ripetendo questo processo alla fine l . Quindi, l ordinato è almeno buono quanto l′ per qualsiasi scelta di l′ , il che significa che è ottimale o legato per ottimale.
Si noti che l'unica proprietà di ( 1 , 2 , . . . , N ) che abbiamo usato è che è ordinato, in modo dallo stesso algoritmo funzionerebbe per permutare qualsiasi elenco di ridurre al minimo la sua distanza ad alcuna lista fisso.
Nel codice, l'unico scopo di z=zip(l,range(len(l)))
è distinguere gli elementi di input, ovvero evitare legami, mantenendo gli stessi confronti tra elementi disuguali. Se l'input garantito non avesse ripetizioni, potremmo rimuoverlo e semplicemente lambda l:map(sorted(l).index,l)
.
v
saranno maggiori di0
? O almeno no0
?