Как уже упоминалось в разделе комментариев к вашему вопросу, отладка может предоставить полезный способ понять, что делает код. Однако позвольте мне представить высокоуровневую перспективу того, что делает ваш код.
Прежде всего, хотя рекурсивных вызовов функции не существует, код, который вы предоставили, является рекурсивным, поскольку все, что он делает, это сохранить свой собственный стек, вместо того, чтобы использовать тот, который предоставляется менеджером памяти вашей ОС , В частности, стек переменных хранит «рекурсивные данные», так сказать, которые передаются от одного рекурсивного вызова другому. Вы могли бы и, возможно, должны рассмотреть каждую итерацию внешнего цикла while в функции в качестве рекурсивного вызова в качестве функции. Если вы это сделаете, вы увидите, что внешний цикл while помогает «рекурсивно» пересекать каждую перестановку nums в глубину в первом порядке.
Заметив это, довольно легко понять, что делает каждый «рекурсивный вызов». В основном, переменная перестановка сохраняет текущую перестановку nums, которая формируется как цикл while. Переменная перестановки хранить все перестановки nums, которые находятся. Как вы можете заметить, перестановки обновляются, только если len (перестановка) равен len (nums), который можно рассматривать как базовый случай отношения повторения, которое реализуется с использованием пользовательского стека. Наконец, внутренний цикл while в основном выбирает, какой элемент nums, чтобы добавить в текущую перестановку (т. Е. Сохраненную в переменной перестановку).
Так вот об этом, действительно. Вы можете выяснить, что именно делается на линиях, относящихся к обслуживанию стек с использованием отладчика, как это было предложено. В качестве заключительного замечания позвольте мне повторить, что я лично не считаю эту реализацию нерекурсивной. Так получилось, что вместо использования абстракции, предоставляемой ОС, это рекурсивное решение сохраняет свой собственный стек. Чтобы лучше понять, каким будет правильное нерекурсивное решение, вы можете увидеть разницу в рекурсивных и итеративных решениях проблемы поиска n th Число Фибоначчи, представленное ниже. Как вы можете видеть, нерекурсивное решение не содержит стека, и вместо того, чтобы делить проблему на более мелкие экземпляры (рекурсия), она создает решение из меньших решений. (Динамическое программирование)
def recursive_fib(n):
if n == 0:
return 0
return recursive_fib(n-1) - recursive_fib(n-2)
def iterative_fib(n):
f_0 = 0
f_1 = 1
for i in range(3, n):
f_2 = f_1 + f_0
f_0 = f_1
f_1 = f_2
return f_1
Вы пробовали переходить через него с помощью отладчика? Хороший способ понять алгоритм. – FujiApple