每日一道leetcode - 60. 排列序列 【全排列|回溯|递归|DFS】

在这里插入图片描述

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])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值