def f(l):z=zip(l,range(len(l)));print map(sorted(z).index,z)
Essayez-le en ligne!
Utilise l'indexation zéro.
Un algorithme rapide avec une idée simple. Si nous avons besoin au lieu de permuter la liste d'entrée pour le rendre aussi proche (1,2,...,n) que possible, nous devrions trier, comme le prouve ci - dessous. Puisque nous sommes à la place permutant (1,2,...,n) , on choisit la permutation que de commander la même manière que la liste d'entrée, comme dans mon défi Imiter un ordre (sauf l'entrée peut avoir des répétitions). (Edit: miles a souligné ce défi plus identique , où Dennis a la même réponse .)
Claim: A permutation of the list l that minimizes its distance to (1,2,...,n) is l sorted.
Proof: Consider some other permutation l′ of l. We'll prove it can't be better than l sorted.
Pick two indices i,j that l′ has out-of-order, that is where i<j but l′i>l′j. We show that swapping them can't increase the distance to (1,2,...,n). We note that swap changes the contribution these two elements as follows:
|l′i−i|+|l′j−j|→|l′i−j|+|l′j−i|.
Here's a neat way to show this can't be an increase. Consider two people walking on a number line, one going from l′i to i and the other from l′j to j. The total distance they walk is the expression on the left. Since i<j but l′i>l′j, they switch who is higher on the number line, which means they must cross at some point during their walks, call it p. But when they reach p, they could then swap their destinations and walk the same total distance. And then, it can't be worse for them to have walked to their swapped destinations from the start rather than using p as a waypoint, which gives the total distance on the right-hand side.
So, sorting two out-of-order elements in l′ makes its distance to (1,2,...,n) smaller or the same. Repeating this process will sort l eventually. So, l sorted is at least as good as l′ for any choice of l′, which means it as optimal or tied for optimal.
Note that the only property of (1,2,...,n) that we used is that it's sorted, so the same algorithm would work to permute any given list to minimize its distance to any fixed list.
In the code, the only purpose of z=zip(l,range(len(l)))
is to make the input elements distinct, that is to avoid ties, while keeping the same comparisons between unequal elements. If the input we guaranteed to have no repeats, we could remove this and just have lambda l:map(sorted(l).index,l)
.
v
seront supérieurs à0
? Ou, du moins, non0
?