我在1分32秒内解决了这个问题。我的解决方案如下。有没有更好的方法来解决它?
def fill_in(letter, word):
perm = []
for i in xrange(len(word)+1):
the_word = word[0:i] + letter + word[i:]
if the_word[0] == '2':
perm.append(the_word)
return perm
def perm(string):
"Find all permutations of given string"
perm_list = []
for i in string:
if len(perm_list) == 0:
perm_list.append(i)
else:
temp = []
while (len(perm_list) != 0):
temp = temp + fill_in (i, perm_list.pop())
perm_list = temp
return perm_list
j = perm("2013456789")
j.sort()
print j[1000000-725760-1]
答案 0 :(得分:2)
对于您当前的算法,可以做的不多。 itertools.permutations
函数会为你做的大部分事情做得更快,但这并不好玩。问题的关键在于,通过聪明的数学,你可以找出答案,而不会产生所有的排列。有关此问题的示例讨论,请访问:http://www.mathblog.dk/project-euler-24-millionth-lexicographic-permutation/
答案 1 :(得分:2)
这是一个简单的代码,可以立即提供答案:
from math import factorial
digits = range(10)
res = []
n = 999999 # PE uses 1-based indexing
for i in xrange(len(digits) - 1, -1, -1):
index, n = divmod(n, factorial(i))
res.append(digits.pop(index))
print ''.join(str(i) for i in res)
它基于阶乘,原理非常简单。假设您有数字1234
,结果为4!
个排列。 3!
第一个排列以1
开头,因此您只需将排列数除以3!
即可得到第一个数字的索引。然后从可用数字中删除数字并将其添加到结果中。对于以下数字,使用前一个除法的余数作为置换数。
答案 2 :(得分:0)
def permutation(order):
start = time.time()
digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # our main list.
original_digits = digits.copy() # take a shallow copy of the list.
i = 1
result = 0
wanted_num = ""
while i <= len(original_digits):
x = 0
while True:
# removing the number of redundant possibilities.
result += factorial(len(original_digits) - i)
x += 1
if result > order - 1:
result -= factorial(len(original_digits) - i)
x -= 1
wanted_num += str(digits[x])
digits.remove(digits[x]) # prevent repetition.
break
i += 1
if result == order and len(digits) == 0:
break
return int(wanted_num), time.time() - start
使用以下行对其进行测试:
print(permutation(1000000))