【发布时间】:2022-01-04 08:52:09
【问题描述】:
这个排列程序中的第二个元素交换是如何工作的? 第二次交换发生在程序的哪一步?在第一次递归之后还是在所有递归完成之后?
def permutations(A: List[int]) -> List[List[int]]:
def directed_permutations(i):
if i == len(A) - 1:
result.append(A.copy())
return
# Try every possibility for A[i]
for j in range(i, len(A)):
A[i], A[j] = A[j], A[i]
# Generate all permutations for A[i + 1:]
directed_permutations(i + 1)
# Second element swap, which I do not understand
A[i], A[j] = A[j], A[i]
result: List[List[int]] = []
directed_permutations(0)
return result
当我离开第二个交换并尝试 A = [2,3,5,7] 时,我得到 4!元素,但有重复:
[[2, 3, 5, 7], [2, 3, 7, 5], [2, 7, 3, 5], [2, 7, 5, 3], [2, 3, 5 , 7], [2, 3, 7, 5], [3, 2, 7, 5], [3, 2, 5, 7], [3, 5, 2, 7], [3, 5, 7 , 2], [3, 2, 7, 5], [3, 2, 5, 7], [5, 2, 3, 7], [5, 2, 7, 3], [5, 7, 2 , 3], [5, 7, 3, 2], [5, 2, 3, 7], [5, 2, 7, 3], [3, 2, 7, 5], [3, 2, 5 , 7], [3, 5, 2, 7], [3, 5, 7, 2], [3, 2, 7, 5], [3, 2, 5, 7]]
通过第二次交换,我得到了正确的 4!元素:
[[2, 3, 5, 7], [2, 3, 7, 5], [2, 5, 3, 7], [2, 5, 7, 3], [2, 7, 5 , 3], [2, 7, 3, 5], [3, 2, 5, 7], [3, 2, 7, 5], [3, 5, 2, 7], [3, 5, 7 , 2], [3, 7, 5, 2], [3, 7, 2, 5], [5, 3, 2, 7], [5, 3, 7, 2], [5, 2, 3 , 7], [5, 2, 7, 3], [5, 7, 2, 3], [5, 7, 3, 2], [7, 3, 5, 2], [7, 3, 2 , 5], [7, 5, 3, 2], [7, 5, 2, 3], [7, 2, 5, 3], [7, 2, 3, 5]]
【问题讨论】:
-
这有点难以理解,因为递归函数正在修改可变数据结构。与不可变数据结构一起使用时,递归感觉要自然得多。在
for循环中发生的情况是,我们想尝试directed_permutations(i+1),将每个可能的元素 A[j] 移动到位置 A[i]。因此,首先我们尝试交换 A[i] 和 A[i]。然后我们撤消交换并尝试交换 A[i] 和 A[i+1]。然后我们撤消交换并尝试交换 A[i] 和 A[i+2]。等等 -
所以,“第二次交换”是第一次交换的“撤消”。
-
@Fortinbras 我同意 Stef 的观点,递归最适合用于持久数据结构。我想你会发现 this Q&A 很有帮助。
标签: python algorithm recursion permutation