No24_Lexicographic permutations

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
时间太长了。。。。
牛人的代码:
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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值