О времени O (n), O (1) пробел для O-Shuffle
Выполнение O-Shuffle в O (n) время и O (1) пространство возможно, но оно жесткое .Не уверен, почему люди думают, что это легко, и предлагают вам попробовать что-то еще.
В следующей статье есть решение O (n) времени и пространства O (1) (хотя это и для случайных комбинаций, но выполнение таких операций делаетперестановка тривиальная):
http://arxiv.org/PS_cache/arxiv/pdf/0805/0805.1598v1.pdf
О методе работы с алгоритмами модификации массивов на месте
Алгоритмы модификации на месте могут стать очень сложными для обработки.
Рассмотрим пару:
- Внесение-тасование в линейное время.Использует теорию чисел.
- Сортировка на месте слияния была открыта в течение нескольких лет.Пришел алгоритм, но он был слишком сложным, чтобы быть практичным.Использует очень сложную бухгалтерию.
Извините, если это звучит обескураживающе, но нет волшебного эликсира, который решит все проблемы с алгоритмом на месте для вас.Вам нужно поработать с проблемой, выяснить ее свойства и попытаться использовать их (как в случае с большинством алгоритмов).
Тем не менее, для модификаций массивов, которые приводят к перестановке Из исходного массива вы можете попробовать метод following the cycles of the permutation
.По существу, любая перестановка может быть записана как непересекающийся набор циклов (см. Также ответ Джона).Например, перестановку:
1 4 2 5 3 6
из 1 2 3 4 5 6
можно записать как
1 -> 1
2 -> 3 -> 5 -> 4 -> 2
6 -> 6.
, стрелку можно прочитать как «идет».
перестановка массива 1 2 3 4 5 6
выполняется три цикла:
1 переходит на 1.
6 переходит на 6.
2 переходит на 3, 3 переходит на 5,5 переходит к 4, а 4 переходит к 2.
Чтобы следовать этому длинному циклу, вы можете использовать только одну временную переменную.Храните 3 в нем.Поставь 2 где 3 было.Теперь поместите 3 в 5 и сохраните 5 в темп и так далее.Поскольку вы используете только постоянное дополнительное временное пространство для следования определенному циклу, вы делаете модификацию массива для этого цикла на месте.
Теперь, если бы я дал вам формулу для вычисления того, куда идет элемент,все, что вам сейчас нужно, это набор начальных элементов каждого цикла.
Разумный выбор начальных точек циклов может упростить алгоритм.Если вы пришли к начальным точкам в пространстве O (1), теперь у вас есть полный алгоритм на месте.Здесь вам, возможно, придется познакомиться с проблемой и использовать ее свойства.
Даже если вы не знали, как вычислить начальные точки циклов, но имели формулу для вычисления следующего элементаВы можете использовать этот метод, чтобы получить O (n) время на месте алгоритм в некоторых особых случаях.
Например: если вы знали, что массив целых чисел со знаком содержит только положительные целые числа.
Теперь вы можете следить за циклами, но отрицать числа в них как индикатор «посещенных» элементов.Теперь вы можете пройтись по массиву и выбрать первое положительное число, с которым вы столкнетесь, и следовать за циклами, делая элементы цикла отрицательными и продолжая находить нетронутыми элементы.В конце вы просто снова делаете все элементы положительными, чтобы получить результирующую перестановку.
Вы получаете O (n) время и O (1) пространство алгоритм!Конечно, мы вроде «обманули», используя знаковые биты целых чисел массива в качестве нашего личного «посещенного» растрового изображения.
Даже если массив не обязательно был целым, этот метод (следуя циклам, а нехак знаковых битов :-)) на самом деле может быть использован для решения двух проблем, которые вы заявляете:
The inshuffle (or out-shuffle) problem
: Когда 2n + 1 - это степень 3, можно показать (используя теорию чисел), что 1,3,3 ^ 2 и т. Д. Находятся в разных циклах, и все циклы охватываются с использованием этих , Объедините это с тем фактом, что перетасовка восприимчива к разделению и завоеванию, вы получаете O (n) время, O (1) пространственный алгоритм (формула i -> 2 * i по модулю 2n + 1). Для получения более подробной информации см. Вышеупомянутый документ.
The cyclic shift an array problem
: циклическое смещение массива размера n на k также дает перестановку результирующего массива (задается формулой i, переходящей в i + k по модулю n), и также может быть решена за линейное время и на месте, используя следующий метод цикла. Фактически, с точки зрения количества обменов элементов этот следующий метод цикла лучше , чем алгоритм 3 обращений. Конечно, следование циклическому методу может привести к уничтожению кэша из-за шаблонов доступа, и на практике алгоритм 3 обращений может на самом деле лучше.
Что касается интервью, если интервьюер - разумный человек, они будут смотреть на то, как вы думаете и подходите к проблеме, а не к тому, решаете ли вы ее на самом деле. Поэтому, даже если вы не решите проблему, я думаю, вам не следует разочаровываться.