class Solution:
def getPermutation(self, n: int, k: int) -> str:
# 全排列问题
def backtrack(n,k,index,path):
# 选完n个数字,结束
if index == n:
return
# 看选定当前数字的情况下所有可能的组合数,是否大于k
# 计算还未确定的数字的全排列的个数,第 1 次进入的时候是 n - 1
# 比如[1,2,3,4],第一层选择了[1],后面有3!种【(n-1)!种】选择
# 如果前面选择了了两个数字,即[1,2],后面就有(n-2)!种选择
cnt = factorial[n-1-index]
for i in range(1,n+1):
if used[i]:
# 用过了,下一个
continue
if cnt < k:
# 如果小于k说明正好不在当前选择的数字的大分支里
# 然后减掉当前分支的所有可能,进入下一个分支选择
k -= cnt
continue
# cnt大于等于k的情况,就说明在当前分支
path.append(i)
used[i] = True
# 剩下的情况
# 注意这里是index+1,而非i+1,因为记录的是前面已经使用过多少个数字了
backtrack(n,k,index+1,path)
# 后面的情况就没必要再遍历了
return
if n == 0:
return ""
# 记录数字是否使用过
used = [False]*(n+1)
path = []
# 可以把从 0-9 的阶乘计算好,放在一个数组里,可以根据索引直接获得阶乘值;
# 比如说当前数组长度为4,取第一个数字之后,剩下三个数字就有3!个可能的组合
factorial = [1]*(n+1)
for i in range(2, n + 1):
factorial[i] = factorial[i - 1] * i
# 此时index为0,之前没有选过数字
backtrack(n,k,0, path)
return ''.join([str(num) for num in path])
每日一道leetcode - 60. 排列序列 【全排列|回溯|递归|DFS】
最新推荐文章于 2024-07-17 09:15:39 发布