def f(l):z=zip(l,range(len(l)));print map(sorted(z).index,z)
Спробуйте в Інтернеті!
Використовує нульову індексацію.
Швидкий алгоритм з простою ідеєю. Якщо замість цього ми повинні переставити список введення , щоб зробити його як можна ближче до (1,2,...,n) , наскільки це можливо, ми повинні просто розбирайтеся, як доведено нижче. Оскільки ми замість перестановки (1,2,...,n) , ми вибираємо перестановку , що замовили точно так же , як список введення, як в моєму виклику Наслідувати впорядкованість ( за винятком введення може бути повтори). (Редагувати: милі вказали на цю більш ідентичну проблему , де Денніс має таку саму відповідь .)
Затвердження: Перестановка зі списку l , що зводить до мінімуму її відстань до (1,2,...,n) є l відсортований.
Доведення: Розглянемо деякі інші перестановки l′ з l . Ми доведемо, що це не може бути краще, ніж l відсортований.
Виберіть два індекси i,j які l′ є поза порядком, тобто i<j але l′i>l′j . Показано , що заміна їх не може збільшити відстань до (1,2,...,n) . Відзначимо, що своп змінює внесок цих двох елементів так:
|l′i−i|+|l′j−j|→|l′i−j|+|l′j−i|.
Ось акуратний спосіб показати, що це не може бути збільшенням. Розглянемо двох людей, що йдуть по лінійці чисел, одна переходить від l′i до i а друга від l′j до j . Загальна відстань, яку вони проходять - це вираз зліва. Оскільки i<j але l′i>l′j , вони перемикають того, хто вище на рядку числа, а це означає, що вони повинні перейти в якийсь момент під час своїх прогулянок, називаючи це p . Але коли вони доходять до p, вони можуть змінити місця призначення та пройти ту саму загальну відстань. І тоді, для них не може бути гірше, що вони пішли до своїх міняних місць призначення з самого початку, а не використовувати p в якості маршрутної точки, яка дає загальну відстань в правій частині.
Так, сортування два поза потоком порядку елементів в l′ робить її відстань до (1,2,...,n) менше або ж. Повторення цього процесу врешті-решт сортуватиме l . Отже, l відсортований як мінімум такий же хороший, як l′ для будь-якого вибору l′ , що означає, що він є оптимальним або прив'язаним до оптимального.
Зверніть увагу , що єдине властивість (1,2,...,n) , який ми використовували в тому , що це сортується, так само алгоритм буде працювати переставляти будь-який даний список , щоб мінімізувати її відстань до будь-якого фіксованого списку.
У коді єдина мета z=zip(l,range(len(l)))
- зробити вхідні елементи різними, тобто уникнути зв’язків, зберігаючи однакові порівняння між нерівними елементами. Якщо введення, яке ми гарантували, не матиме повторів, ми можемо це видалити і просто мати lambda l:map(sorted(l).index,l)
.
v
, буде більше, ніж0
? Або, принаймні, ні0
?