A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:
012 021 102 120 201 210
What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?
代码为:
def kinds(inlist):
if not inlist:
return []
relist=[]
for tempint in inlist:
templist=inlist[:]
templist.remove(tempint)
inner_relist=kinds(templist)
if not inner_relist:
relist.append([tempint])
else:
for temp_relist in inner_relist:
temp_relist.insert(0,tempint)
relist.append(temp_relist)
return relist
import datetime
start_time=datetime.datetime.now()
outlist=kinds([0,1,2,3,4,5,6,7,8,9])
print outlist[1000000-1]
end_time=datetime.datetime.now()
print end_time-start_time
运行结果为:
[2, 7, 8, 3, 9, 1, 5, 4, 6, 0]
0:00:24.134000
0:00:24.134000
时间太长了。。。。
牛人的代码:
2783915460
Time taken = 0:00:00 microseconds
牛人的代码:
import datetime,math
# Here's a cool way to solve this problem. Figure out the problem digit by digit.
# First the sorted digits are [0,1,2,3,4,5,6,7,8,9] so let's figure out where
# the millionth permutation will lie. This is easy to figure out since the
# permutations are sorted. We know that in this sorted permutation list, we will
# have 10! = 3628800 permutations and they will appear as follows: 362880 permutation
# with '0' as the first digit, 362880 with '1' as the first digit, 362880 with '2'
# as the first digit, and so on for a total of 362880*10 = 3628800 permutations. Now
# 1000000 lies somwhere between 362880*3 and 362880*4, therefore we know for certain
# that the first digit has to be the third one in the list, i.e., 2. Now, for the
# next digit, instead of looking for 1000000, we will look for 1000000 - (362880*3)
# and follow the same procedure using the 8 remaining digits [0,1,3,4,5,6,7,8,9].
def fact(n):
if n == 0:
return 1
else:
return n * fact(n-1)
start_time=datetime.datetime.now()
digits = range(10)
answer = []
idx = 1000000
numdigits = 10
while len(digits) != 1:
a = fact(numdigits-1)
b = int(math.ceil(idx/float(a)))
thisdigit = digits[b-1]
answer.append(thisdigit)
digits.remove(thisdigit)
idx = idx - (a*(b-1))
numdigits = numdigits - 1
else:
answer.append(digits[0])
print ''.join([str(x) for x in answer])
endtime=datetime.datetime.now()
print "Time taken =", endtime-start_time, "microseconds"
运行结果为:
2783915460
Time taken = 0:00:00 microseconds