我编写了一个递归函数来生成长度为X的所有有序排列的列表,用于字符列表。
例如:[' a'' b',' c',' d'] X = 2会给[ [' a'' a'],[' a'' b'],[' a', ' c'],[' a'' d'],[' b'' a'], [' b',' b'],...,[' d',' d']]
我不确定它的算法复杂程度(至少我知道它非常可怕)。我想说的是:
O(X * N ^(L + X))
(其中L是不同字符的数量,4这里是因为我们有' A'' B',' C',' D& #39;,和X我们想要生成的排列的长度)。 因为我有2个嵌套循环,它将运行X次(好吧,X-1因为X = 1时的特殊情况)。 这是对的吗?
def generate_permutations(symbols, permutations_length):
if permutations_length == 1:
return [[symbol] for symbol in symbols]
tails = generate_permutations(symbols, permutations_length-1)
permutations = []
for symbol in symbols:
for tail in tails:
permutation = [symbol] + tail
permutations.append(permutation)
return permutations
print(generate_permutations(['a', 'b', 'c', 'd'], 2))
顺便说一句:我知道这不是惯用的Python,如果它丑陋我会道歉但是我只是在用不同的,不那么富有表现力的语言编写代码之前做的一些原型设计。 而且我也知道我可以使用itertools.permutations来完成这项任务。顺便说一句,如果有人碰巧知道itertool的排列函数的算法复杂性,并且有一些方法可以提高我自己的算法的复杂性,我会感兴趣。
谢谢!
答案 0 :(得分:0)
X
= 1时生成的步骤数:
N(1) = L
在递归步骤中,步数是X-1
的步数,由于递归调用,加上L * N(X-1)
由于循环:
N(X) = N(X-1) + L * N(X-1)
显然L * N(X-1)
支配N(X-1)
,因此我们可以忽略N(X-1)
一词。
渐近成本为 O(L ^ X)。
L X 恰好也是结果中项目的数量,因此使用python列表获得更好的渐近成本是不可能的。
答案 1 :(得分:0)
在数学上,所有有序排列本身的数量等于 L P X ,如wiki所述。< / p>
L P X = L*(L-1)*..*(L-X+1)
大约等于L X 。
现在,长度X
的每个最终排列都是通过在现有字符串长度中一次添加一个字符逐步生成的,即总复杂度值O(1+2+3+..+X)
或 O(X 2 )强>
最后,你的python实现实际上是最佳递归的一个例子,并且算法复杂度为 O(X 2 * L P X < /子>)强>