Ответ 1
Похоже, я собираюсь ответить на свой вопрос утвердительно - да, next_permutation
работает в O (1) амостатированном времени.
Прежде чем перейти к формальному доказательству этого, быстро перейдем к тому, как работает алгоритм. Во-первых, он сканирует назад от конца диапазона к началу, идентифицируя самую длинную смежную уменьшающуюся подпоследовательность в диапазоне, который заканчивается на последнем элементе. Например, в 0 3 4 2 1
алгоритм идентифицирует 4 2 1
как эту подпоследовательность. Затем он смотрит на элемент прямо перед этой подпоследовательностью (в приведенном выше примере 3), затем находит наименьший элемент в подпоследовательности, большей, чем он (в приведенном выше примере, 4). Затем обменивается позициями этих двух элементов, а затем меняет указанную последовательность. Итак, если мы начали с 0 3 4 2 1
, мы заменили бы 3 и 4, чтобы получить 0 4 3 2 1
, и затем перевернем последние три элемента, чтобы получить 0 4 1 2 3
.
Чтобы показать, что этот алгоритм работает в амортизированном O (1), мы будем использовать метод потенциала. Определить & Phi; в три раза больше длины самой длинной смежно уменьшающейся подпоследовательности в конце последовательности. В этом анализе мы будем предполагать, что все элементы различны. Учитывая это, подумайте о времени выполнения этого алгоритма. Предположим, что мы сканируем назад от конца последовательности и обнаруживаем, что последние m элементов являются частью уменьшающейся последовательности. Для этого требуется сравнение m + 1. Затем мы найдем элементы этой последовательности, один из которых является наименьшим, большим, чем элемент, предшествующий этой последовательности. Это занимает наихудшее время, пропорциональное длине уменьшающейся последовательности, используя линейное сканирование для других m сравнений. При замене элементов требуется, скажем, 1 кредитная оценка времени, а для изменения последовательности требуется не более т операций. Таким образом, реальное время выполнения этого шага составляет примерно 3m + 1. Однако мы должны учитывать изменение потенциала. После того, как мы отменим эту последовательность длины m, мы заканчиваем тем, что уменьшаем длину самой длинной убывающей последовательности в конце диапазона до длины 1, так как обратное уменьшение последовательности в конце делает последние элементы диапазона отсортированными в порядке возрастания, Это означает, что наш потенциал изменился с & Phi; = 3 м до & Phi; ' = 3 * 1 = 3. Следовательно, чистое падение потенциала составляет 3 - 3 м, поэтому наше чистое амортизированное время равно 3m + 1 + (3 - 3m) = 4 = O (1).
В предыдущем анализе я сделал упрощающее предположение о том, что все значения уникальны. Насколько мне известно, это предположение необходимо для того, чтобы это доказательство работало. Я подумаю об этом и посмотрю, может ли доказательство быть изменено для работы в случае, когда элементы могут содержать дубликаты, и я опубликую отредацию этого ответа, когда я обработаю детали.