Нахождение каждой перестановки не занимает O(N^2)
.Создание каждой перестановки происходит за O(1)
время.Хотя заманчиво сказать, что это O(N)
, поскольку вы назначаете новый элемент каждому индексу N
раз на перестановку, каждая перестановка делит назначения с другими перестановками.
Когда мы делаем:
a[l], a[i] = a[i], a[l]
permute(a, l+1, r, b)
Все последующие рекурсивные вызовы permute
на линии имеют это назначение уже на месте.
В действительности, назначения происходят только каждыйвремя permute
называется, то есть
раз.Затем мы можем определить сложность времени для построения каждой перестановки, используя некоторое предельное исчисление.Мы берем количество назначений за общее число перестановок, когда N приближается к бесконечности.
Имеется:
![enter image description here](https://i.stack.imgur.com/BOF5n.png)
Расширение сигмы:
![enter image description here](https://i.stack.imgur.com/aaqlt.png)
Лимит суммы является суммой лимитов:
![enter image description here](https://i.stack.imgur.com/FzBeO.png)
На данный момент мы оцениваем наши лимиты и все условиякроме первого обвала до нуля.Поскольку наш результат является константой, мы получаем, что наша сложность для каждой перестановки равна O(1)
.
![enter image description here](https://i.stack.imgur.com/asLQO.png)
Однако мы забываем об этой части:
if l==r:
if a==b:
result = True
Сравнение a == b
(между двумя списками) происходит в O(N)
.Построение каждой перестановки занимает O(1)
, но наше сравнение в конце, которое происходит для каждой перестановки, на самом деле занимает O(N)
.Это дает нам временную сложность O(N)
для каждой перестановки.
Это дает вам N!
раз перестановок O(N)
для каждой перестановки, что дает вам общую временную сложность O(N!) * O(N)
= O(N * N!)
.
Ваша окончательная временная сложность не уменьшается до O(N!)
, поскольку O(N * N!)
все еще на порядок больше O(N!)
, и отбрасываются только постоянные члены (та же причина, по которой O(NlogN) != O(N)
).