Python 使用递归查找数组的排列

Python 使用递归查找数组的排列,python,Python,我提出了以下功能: def permutations(elements, arr, index): if len(elements) == index: print arr for i in xrange(index, len(elements)): arr[index] = elements[i] permutations(elements, arr, index+1) permutations([1,2,3], [0,0,0]

我提出了以下功能:

def permutations(elements, arr, index):
    if len(elements) == index:
        print arr
    for i in xrange(index, len(elements)):
        arr[index] = elements[i]
        permutations(elements, arr, index+1)

permutations([1,2,3], [0,0,0], 0)
但是,它正在打印:

[1, 2, 3]
[1, 3, 3]
[2, 2, 3]
[2, 3, 3]
[3, 2, 3]
[3, 3, 3]

我的递归怎么了

代码中的主要问题是,在
i-th
位置上,只有可能的值来自
(i,n-1)
,其中是列表的n长度。这就是为什么在列表的最后一个索引中,您拥有所有3个。因此,解决方案是在
(0,n-1)
的所有“级别”(
i-th
置换调用)上迭代。但是,因为您将在所有“级别”上从
(0,n-1)
进行迭代,所以必须引入字典(用作哈希集),如果在以前的调用中已经选择了某个值(
j-th
元素),您将保留该字典。最简单的解决方案如下:

def perm(elements):
    def inner(arr, index, visited):
        if len(elements) == index:
            print arr
        for i in xrange(0, len(elements)):
            if (i not in visited):
                visited[i] = 1; # mark so same index can not be used later
                arr[index] = elements[i]
                inner(arr, index + 1, visited);
                del visited[i] # free index
    inner([0] * len(elements), 0, {});         

perm([1,2,3])
正如@Hooked已经提到的,如果您可以使用它,那么它将是最好的。注意,在Python3上,您可以使用
非本地
将arr和visitored置于函数参数之外。此外,这里还有一个解决方案,没有字典,但有额外的列表,其中包含排列的
i-th
级别(位置)的所有可能值。然而,在这个解决方案中,排列顺序不被保留

def perm(elements):
    def inner(arr, index, possible):
        if len(elements) == index:
            print arr
        lenForLevel = len(elements) - index;
        for i in xrange(0, lenForLevel):            
            arr[index] = possible[i]
            (possible[i], possible[lenForLevel - 1]) = (possible[lenForLevel - 1], possible[i])
            inner(arr, index + 1, possible);
            (possible[i], possible[lenForLevel - 1]) = (possible[lenForLevel - 1], possible[i])
    inner([0] * len(elements), 0, list(elements))

perm([1,2,3,4])

好的,我发现这是一个Java字符串递归置换算法,我把它翻译成Python。我认为这是最好的解决方案:

def permutation(aux, ls):
    if len(ls) == 0: 
        print(aux)
    else:
        for i in range(len(ls)):
            permutation(aux + [ls[i]], ls[0:i] + ls[i+1:len(ls)])

permutation([], [1, 2, 3])
这是输出:

[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]

试着看看这里:请注意,如果您只需要一个有效的解决方案:向上投票,那么可以使用
itertools
来实现这一点。非常简洁的解决方案:)另外,我的更快一些(ls[0:i]+ls[i+1:len(ls)]是O(n)),即使是第二个也不能保持排列顺序