Когда мы сортируем список, например
a = [1,2,3,3,2,2,1]
sorted(a) => [1, 1, 2, 2, 2, 3, 3]
равные элементы всегда смежны в результирующем списке.
Как я могу достичь противоположной задачи - перетасовать список, чтобы равные элементы никогда (или как можно реже) не смежны?
Например, для приведенного выше списка одним из возможных решений является
p = [1,3,2,3,2,1,2]
Более формально, учитывая список a
, сгенерируйте его перестановку p
, которая минимизирует число пар p[i]==p[i+1]
.
Поскольку списки велики, генерация и фильтрация всех перестановок не является опцией.
Бонусный вопрос: как эффективно генерировать все такие перестановки?
Это код, который я использую для тестирования решений: https://gist.github.com/gebrkn/9f550094b3d24a35aebd
UPD: Выбор победителя здесь был трудным выбором, потому что многие люди оставили отличные ответы. @VincentvanderWeele, @David Eisenstat, @Coady, @enrico.bacis и @srgerg предоставили функции, которые генерируют наилучшую возможную перестановку безупречно. @tobias_k, и Дэвид также ответил на бонусный вопрос (сгенерировал все перестановки). Дополнительные указания Дэвиду относительно доказательства правильности.
Код из @VincentvanderWeele представляется самым быстрым.