leetcode 每日一题 60. 第k个排列
阶乘法
思路:
因为集合[1,2,3,...,n]共有n!种排列,则[1,2,3,...,n-1]有(n-1)!种排列。由此可以看出,在[1,2,3,...,n]所有的排列中,第一位有n种可能,为1--n,并且每个确定的第一位数均有(n-1)!种排列。同理,在确定第二位数的情况下,有(n-2)!种排列,在确定第m位数的情况下,有(n-m)!种可能。则在按大小顺序n位数排列的全排列中,寻找第k个排列。可以用num1=k/(n-1)! 来确定第一位数,用num2=(k-num1*(n-1)!)/(n-2)!来确定第二位数,同理可以依次确定后面几位数。这里要注意的是,在[1,2,3,4,..,n]中,,每确定一位数,则在集合中删除对应确定的数字,在剩余有顺序的数中继续找。
例如:
n = 3 ,k = 3 则集合为nums = [1,2,3]
考虑到nums的下标为 0 到 n! - 1 先将k = k-1 = 2
2/(3-1)!= 1 则第一位数为nums[1] = 2 剩余集合nums = [1,3]
2-1*(3-1)!)/ (3-2)! = 0 则第二位数为nums[0] = 1 剩余集合 nums = [3]
(2-1*(3-1)!-0*(3-2)!) / (3-3)! = 0 则第三位数为nums[0] = 3 得结果 '213'
代码:
class Solution: def getPermutation(self, n: int, k: int) -> str: factorials, nums = [1], ['1'] for i in range(1, n): factorials.append(factorials[i - 1] * i) nums.append(str(i + 1)) k -= 1 output = [] for i in range(n - 1, -1, -1): idx = k // factorials[i] k -= idx * factorials[i] output.append(nums[idx]) del nums[idx] return ''.join(output)