def f(l):z=zip(l,range(len(l)));print map(sorted(z).index,z)
Experimente online!
Usa indexação zero.
Um algoritmo rápido com uma ideia simples. Se em vez precisam permutar a lista de entrada para torná-lo tão perto de (1,2,...,n) que possível, devemos apenas uma espécie, como comprovado abaixo. Desde que nós estamos permutando vez ( 1 , 2 , . . . , N ) , nós escolhemos a permutação daquele ordenado da mesma forma que a lista de entrada, como no meu desafio Imitar uma ordenação (exceto a entrada pode ter repete). (Edit: miles apontou esse desafio mais idêntico , onde Dennis tem a mesma resposta .)
Reivindicação: Uma permutação da lista eu que minimiza a sua distância a ( 1 , 2 , . . . , N ) é eu classificados.
Prova: considere alguma outra permutação eu′ de eu . Vamos provar que não pode ser melhor do que eu resolvi.
Escolha dois índices i , j que eu′ está fora de ordem, que é onde eu < j mas eu′Eu> l′j . Mostramos que a troca deles não pode aumentar a distância de ( 1 , 2 , . . . , N ) . Observamos que o swap altera a contribuição desses dois elementos da seguinte maneira:
| eu′Eu- i | + | eu′j- j | → | eu′Eu- j | + | eu′j- i | .
Aqui está uma maneira elegante de mostrar que isso não pode ser um aumento. Considere duas pessoas andando em uma linha numérica, uma que vai de eu′Eu para Eu a outra de eu′j para j . A distância total que andam é a expressão à esquerda. Como eu < j mas eu′Eu> l′j , eles trocam quem é mais alto na linha numérica, o que significa que devem atravessar em algum momento de suas caminhadas, chame de p . Mas quando eles atingem p, eles poderiam trocar seus destinos e percorrer a mesma distância total. E então, não pode ser pior para eles terem caminhado para seus destinos trocados desde o início, em vez de usar p como um waypoint, o que fornece a distância total no lado direito.
Assim, dois elementos de triagem para fora-de-fim em eu′ faz com que o seu raio de ( 1 , 2 , . . . , N ) menor ou o mesmo. Repetindo este processo irá classificar eu eventualmente. Portanto, eu classificado é pelo menos tão bom quanto eu′ para qualquer escolha de eu′ , o que significa ótimo ou vinculado ao ideal.
Note-se que a única propriedade de ( 1 , 2 , . . . , N ) que usamos é que ele é classificado, de modo que o mesmo algoritmo iria trabalhar para permutar qualquer lista dada para minimizar o seu raio de qualquer lista fixa.
No código, o único objetivo de z=zip(l,range(len(l)))
é diferenciar os elementos de entrada, ou seja, evitar vínculos, mantendo as mesmas comparações entre elementos desiguais. Se a entrada que garantimos não tiver repetições, poderíamos removê-la e apenas ter lambda l:map(sorted(l).index,l)
.
v
serão maiores que0
? Ou pelo menos não0
?