【题目】
The set [1,2,3,…,n] contains a total of n! uniquepermutations.
By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):
"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutationsequence.
Note: Given n will be between 1 and 9 inclusive.
【思路】
l DFS思想,按顺序找出所有组合方式,这种暴力方式会LTE
l 从排列组合方式中找寻规律:
对于1-n,n个数的全排列方式有n!种;
固定第一位为某数字,有(n-1)!种
当n = 6时:
比如第一位是1的共有5! = 120种;
第一位是2的k至少要为121,以2开头的也有120种;
若k = 481,则第一位应该以数字4开头(准确的说排列为412356)
若k = 520,则第一位应该以数字5开头
固定前两位有(n-2)!种:
当 n = 6, k = 520时,第一位为5,接下来需要确定第二位
第一位为5的情况下:第二位为1时有4!= 24种,由于480+24=504固第二位为 2时k至少为505 ,由于504+24=528,固第二位为3时k至少为529,因此第二位 为2。
因此当 n = 6, k= 520时应该为52****
按照这个规律可以计算出524361
Note:
因为数字不能重复,某个数字若使用过,则不能使用。
每次循环找到没使用过的数中第k/data[i]个数就是当前位的数字。
【Python实现】
class Solution(object):
def getPermutation(self, n, k):
"""
:type n: int
:type k: int
:rtype: str
"""
nums = [str(i) for i in range(1,n+1)]
res = []
self.DFS(res, [], nums)
return res[k-1]
def DFS(self, res, L1, nums):
if len(nums) == 0:
res.append("".join(L1))
#print(res)
for i in range(len(nums)):
L1.append(nums[i])
#print("i = %d"%i)
self.DFS(res, L1, nums[:i] + nums[i+1:])
L1.pop()#最后一个元素出栈
def main():
sol = Solution()
n = 8
k = 31492
print(sol.getPermutation(n,k))
if __name__ == "__main__":
import time
start = time.clock()
Solution.main()
print( "%s sec" % (time.clock() - start))
方法二:
class Solution:
"""
:type n: int
:type k: int
:rtype: str
"""
def getPermutation(self, n, k):
res = ''
k -= 1
fac = 1
for i in range(1, n): #第一位确定时的全排列数量
fac *= i
num = [str(i) for i in range(1,n+1)]
print(num)
for i in reversed(range(n)):
curr = num[k//fac]#下标是k//fac的数字
res += str(curr)
num.remove(curr)#使用过的数字移除
if i !=0:
k %= fac
fac = fac//i #再固定一位时候的全排列数量
return res
def main():
sol = Solution()
n = 6
k = 520
print(sol.getPermutation(n,k))
if __name__ == "__main__":
import time
start = time.clock()
Solution.main()
print( "%s sec" % (time.clock() - start))