1 class Solution: 2 def groupSize(self,k):#计算阶乘 3 gSize = 1 4 while k != 0: 5 gSize *= k 6 k -= 1 7 return gSize 8 9 def getUnlockNum(self,nums,idx): 10 pos = 0 11 for i in range(len(nums)): 12 if nums[i] == 0: 13 pos += 1 14 if pos == idx: 15 nums[i] = 1 16 return str(i + 1) 17 18 def getPermutation(self, n: int, k: int) -> str: 19 count = 0#记录拼接字符串的长度 20 bloks = [0] * n#记录锁定状态 21 res = '' 22 for i in range(n): 23 gSize = self.groupSize(n-count-1)#每组多少个 24 groups = n-count#共分几组 25 if groups == 1: 26 res += self.getUnlockNum(bloks,1) 27 else: 28 s = k // gSize 29 p = k % gSize 30 fixed = 0 31 if p > 0: 32 fixed += 1 33 groupNum = s + fixed#第几组(从1开始计数) 34 res += self.getUnlockNum(bloks,groupNum) 35 if p != 0: 36 k = p#更新k值为本次计算的余数 37 else: 38 k = gSize 39 count += 1#记录res的长度 40 return res
流程分析,以(4,9)为例:
4 * 3 * 2 * 1 = 24
第一位数字的选择
按 3 * 2 * 1 = 6 个为一组,共24个,则分4组
1-6 第一组
7-12 第二组
13-18 第三组
19-24 第四组
被除数为9,除数为6
9 // 6 = 1
9 % 6 = 3 > 0
因此9 是第二组
在 1 2 3 4 中,从左向右遍历,找到第2个未锁定的数字2,并将其锁定,返回此数字
数组的状态变为1 [2] 3 4
第二位数字的选择
按 2 * 1 = 2 个为一组,共6个,则分3组
1-2 第一组
3-4 第二组
5-6 第三组
被除数为之前的余数3,除数为2
假如余数是0,则被除数等于之前的每组个数
3 // 2 = 1
3 % 2 = 1 > 0
因此3 是第二组
在 1 [2] 3 4 中,从左向右遍历,找到第2个未锁定的数字3,并将其锁定,返回此数字
数组的状态变为 1 [2] [3] 4
第三位数字的选择
按 1 = 1 个为一组,共2个,则分2组
1 第一组
2 第二组
被除数为之前的余数1,除数为1
假如余数是0,则被除数等于之前的每组个数
1 // 1 = 1
1 % 1 = 0 == 0
因此1 是第1组
在 1 [2] [3] 4 中,从左向右遍历,找到第1个未锁定的数字1,并将其锁定,返回此数字
数组的状态变为 [1] [2] [3] 4
第四位数字的选择
由于未被锁定的数字只剩下1位,因此直接返回此数字,得到最终结果