(0 <= i < n)
的第i个元素(0 <= k < n!)
?可以选择排列的任何顺序,它不必是词典。有些算法在k
中构建O(n)
- 排列(见下文)。但是这里不需要完整的排列,只需要它的第i
个元素。是否有比O(n)
更好的算法?
有些算法通过处理大小为k
的数组(见下文)来构造n
- 排列,但对于大n
,空间要求可能不合需要。是否存在需要较少空间的算法,尤其是当仅需要i
个元素时?
使用时间和空间复杂度k
来构造序列0..n-1
的{{1}} - 排列的算法:
O(n)
来源:http://webhome.cs.uvic.ca/~ruskey/Publications/RankPerm/MyrvoldRuskey.pdf
答案 0 :(得分:1)
你可能无法得到O(n)时间或空间中n个元素的第k个排列的第i个数字,因为表示数字k本身需要O(log(n!))= O(n log) n)位,对它的任何操作都有相应的时间复杂度。
答案 1 :(得分:1)
jkff说的是什么。你可以像你发布的那样修改一个算法,只返回第k个排列的第i个元素,但你不会节省很多时间(或空间),你肯定不会减少Big-O基本算法的复杂性。
您发布的无序排列代码实际上并不适合修改,因为它必须遍历执行其交换的所有元素,并且确定是否可能破坏它是很痛苦的早早离开了。
但是,有一个类似的算法可以产生有序排列,并且可以提前突破那个,但你仍然需要执行i
内部循环来获得第i个元素。第k个排列。
我已将此算法实现为一个类,只是为了保持它使用的各种常量整洁。下面的代码产生完整的排列,但是应该很容易修改以返回第i个元素。
#!/usr/bin/env python
''' Ordered permutations using factorial base counting
Written by PM 2Ring 2015.02.15
Derived from C code written 2003.02.13
'''
from math import factorial
class Permuter(object):
''' A class for making ordered permutations, one by one '''
def __init__(self, seq):
self.seq = list(seq)
self.size = len(seq)
self.base = factorial(self.size - 1)
self.fac = self.size * self.base
def perm(self, k):
''' Build kth ordered permutation of seq '''
seq = self.seq[:]
p = []
base = self.base
for j in xrange(self.size - 1, 0, -1):
q, k = divmod(k, base)
p.append(seq.pop(q))
base //= j
p.append(seq[0])
return p
def test(seq):
permuter = Permuter(seq)
for k in xrange(permuter.fac):
print '%2d: %s' % (k, ''.join(permuter.perm(k)))
if __name__ == '__main__':
test('abcd')
这个算法比无序置换制造者有更多的开销:它需要提前计算阶乘,当然阶乘非常快。而且,每个内环需要一个额外的分区。因此,一旦找到第i个元素,从内循环中拯救的时间可能会被这些开销所抵消。
FWIW,你问题中的代码还有改进的余地。特别是,k /= n
应写为k //= n
以确保使用整数除法;你的代码在Python 2上工作正常,但在Python 3上没有。但是,由于我们需要商和余数,所以使用内置的divmod()
函数是有意义的。此外,通过重新组织一些东西,我们可以避免n - 1
#!/usr/bin/env python
def kth_permutation(n, k):
p = range(n)
while n:
k, j = divmod(k, n)
n -= 1
p[n], p[j] = p[j], p[n]
return p
def test(n):
last = range(n)
k = 0
while True:
p = kth_permutation(n, k)
print k, p
if p == last:
break
k += 1
test(3)
<强>输出强>
0 [1, 2, 0]
1 [2, 0, 1]
2 [1, 0, 2]
3 [2, 1, 0]
4 [0, 2, 1]
5 [0, 1, 2]