def f(l):z=zip(l,range(len(l)));print map(sorted(z).index,z)
Wypróbuj online!
Wykorzystuje indeksowanie zerowe.
Szybki algorytm z prostym pomysłem. Gdybyśmy zamiast tego trzeba permutacji listę wejściowy, aby go jak najbliżej (1,2,...,n) , jak to możliwe, powinniśmy po prostu rodzaj to, jak udowodniono poniżej. Ponieważ jesteśmy zamiast permutacji (1,2,...,n) , wybieramy permutacji że zamówione w ten sam sposób jak listy wejściowej, jak w moim wyzwaniem Naśladuj uporządkowanie (z wyjątkiem wejścia mogą mieć powtórzeń). (Edycja: mile wskazało na to bardziej identyczne wyzwanie , na które Dennis ma tę samą odpowiedź ).
Twierdzenie: permutacją lista l , która minimalizuje jej odstęp (1,2,...,n) jest l sortowane.
Dowód: Zastanów się nad inną permutacją l′ z l . Będziemy udowodnić, że nie może być lepiej niż l sortowane.
Wybierz dwa indeksy i,j że l′ ma kolejność, czyli gdzie i<j ale l′i>l′j . Możemy zobaczyć, że ich wymiany nie może zwiększyć odległość (1,2,...,n) . Zwracamy uwagę, że zmienia wymiany wkładu tych dwóch elementów w następujący sposób:
|l′i−i|+|l′j−j|→|l′i−j|+|l′j−i|.
Oto fajny sposób, aby pokazać, że nie może to być wzrost. Rozważmy dwie osoby idące po linii liczbowej, jedna biegnie od l′i do i a druga od l′j do j . Całkowity dystans, jaki pokonują, jest wyrażeniem po lewej stronie. Ponieważ i<j ale l′i>l′j , zmieniają, kto jest wyższy na linii liczbowej, co oznacza, że muszą przejść w pewnym momencie podczas spacerów, nazywają to p . Ale kiedy osiągną p, mogliby następnie zamienić swoje miejsca docelowe i przejść ten sam łączny dystans. A potem nie może być gorsze, że od samego początku szli do zamienionych miejsc docelowych, zamiast używać p jako punktu pośredniego, co daje całkowity dystans po prawej stronie.
Tak więc, dwie sortowania poza kolejnością elementów w l′ sprawia, że jej odległość do (1,2,...,n) mniejsze lub sam. Powtarzając ten proces będzie sortować l ostatecznie. Tak więc, sortowane l jest co najmniej tak dobre jak l′ dla dowolnego wyboru l′ , co oznacza, że jest tak optymalne lub powiązane dla optymalnego.
Należy pamiętać, że tylko własność (1,2,...,n) , które użyliśmy jest to, że sortowane, tak samo algorytm będzie działać do permutacji dowolną listę zminimalizować dystans do dowolnej ustalonej listy.
W kodzie jedynym celem z=zip(l,range(len(l)))
jest rozróżnienie elementów wejściowych, czyli uniknięcie powiązań, przy jednoczesnym zachowaniu tych samych porównań między nierównymi elementami. Jeśli dane wejściowe gwarantujemy, że nie będziemy powtarzać, możemy to usunąć i po prostu mieć lambda l:map(sorted(l).index,l)
.
v
, będą większe niż0
? A przynajmniej nie0
?