Python 如何仅通过一次交换找到字符串的所有可能排列?

Python 如何仅通过一次交换找到字符串的所有可能排列?,python,string,algorithm,permutation,Python,String,Algorithm,Permutation,复杂性应该是O(n),其中n是字符串的长度。 例:对于“abc”,答案是“bac”、“cba”、“acb”。 “bca”和“cab”不应在列表中,因为将其转换为“abc”需要两个掉期 我已经做了一个O(n2)算法,但它非常慢 def f(s): temp=list(s) l=[] for i in range(len(s)): for j in range(len(s)): temp=list(s) temp

复杂性应该是O(n),其中n是字符串的长度。 例:对于“abc”,答案是“bac”、“cba”、“acb”。 “bca”和“cab”不应在列表中,因为将其转换为“abc”需要两个掉期

我已经做了一个O(n2)算法,但它非常慢

def f(s):
    temp=list(s)
    l=[]
    for i in range(len(s)):
        for j in range(len(s)):
            temp=list(s)
            temp[i],temp[j]=temp[j],temp[i]
            l.append("".join(str(i) for i in temp))
    print set(l)

使用
itertools.combines
查找两个字符索引的所有可能组合,然后将其交换

# -*- coding: utf-8 -*-
import itertools


def f(s):
    result = []
    # This will produce: [0, 1], [0, 2], [1, 2]
    for idx1, idx2 in itertools.combinations(range(len(s)), 2):
        swapped_s = list(s)
        swapped_s[idx1], swapped_s[idx2] = swapped_s[idx2], swapped_s[idx1]
        result.append(''.join(swapped_s))
    return result

if __name__ == '__main__':
    print f('abc')
上述代码将为您提供正确的结果:

['bac', 'cba', 'acb']

希望有帮助

使用
itertools.combines
查找两个字符索引的所有可能组合,然后将其交换

# -*- coding: utf-8 -*-
import itertools


def f(s):
    result = []
    # This will produce: [0, 1], [0, 2], [1, 2]
    for idx1, idx2 in itertools.combinations(range(len(s)), 2):
        swapped_s = list(s)
        swapped_s[idx1], swapped_s[idx2] = swapped_s[idx2], swapped_s[idx1]
        result.append(''.join(swapped_s))
    return result

if __name__ == '__main__':
    print f('abc')
上述代码将为您提供正确的结果:

['bac', 'cba', 'acb']

希望有帮助

长度为
n
的字符串(具有不同字符)的可能结果数为
nC2=n*(n-1)/2
,因为我们可以在任意两个索引中选择两个字母并交换它们

因此,如果您计划打印所有结果,那么复杂性将是
O(n^2)
,而
O(n)
解决方案是不可能的


对于重复字符,推理变得更加复杂。假设只有一个重复字符重复
k次
。然后是相同的
n-k
swap。因此,如果只重复了一个字符,并且重复了
k次
,那么可能性的数量是
nC2-(n-k)
。这可以使用包含排除原则扩展到更多重复的字符。

长度为
n
的字符串(具有不同字符)的可能结果数为
nC2=n*(n-1)/2
,因为我们可以在任意两个索引中选择两个字母并交换它们

因此,如果您计划打印所有结果,那么复杂性将是
O(n^2)
,而
O(n)
解决方案是不可能的


对于重复字符,推理变得更加复杂。假设只有一个重复字符重复
k次
。然后是相同的
n-k
swap。因此,如果只重复了一个字符,并且重复了
k次
,那么可能性的数量是
nC2-(n-k)
。这可以使用包含排除原理扩展到更多的重复字符。

不可能有任何O(n)解,因为有超过O(n)个答案。您可以将任何元素与任何其他元素交换,因此有n(n-1)/2个解,并且您的O(n²)算法是最优的。但是,始终转换为列表和联接真的明智吗?不可能有任何O(n)解,因为有多个O(n)解。您可以将任何元素与任何其他元素交换,因此有n(n-1)/2个解,并且您的O(n²)算法是最优的。但是,一直转换为列表并加入真的明智吗?如果我们有重复的字符怎么办?如果我们有重复的字符怎么办?