leetcode 60. 排列序列 python

题目描述:

 

题解一:回溯 超时

1.和之前的利用回溯解决排列组合的问题思路类似。

2.为了减少运行时间,只搜索前k种组合(通过当前res中组合的数量控制)

3.返回值是str形式,需要加一步处理。

class Solution(object):
    def getPermutation(self, n, k):
        res = []
        depth = 0
        used = [0 for i in range(n)]
        nums = [str(i) for i in range(1,n+1)]
        self.dfs(n,k,nums,[],res,used,depth)
        result = "".join(res.pop())
        return result

    def dfs(self,n,k,nums,path,res,used,depth):
        if len(res)<k:
            if depth == n:
                res.append(path[:])
            for i in range(n):
                if used[i] == 0:
                    used[i] = 1
                    path.append(nums[i])
                    depth = depth + 1
                    self.dfs(n, k, nums, path, res, used, depth)
                    used[i] = 0
                    path.pop()
                    depth = depth - 1

结果还是超时了

 题解二:剪枝,只搜索包含第k个解的子树

参考:​​​​​​力扣

思路:如果当前子树的所有组和不包含第k个,则直接跳过该分支,不进行搜索!

当前子树所有组合数量可以用(n-1)!计算,跳过某个子树的时候需要更新k的值。

class Solution(object):
    def getPermutation(self, n, k):
        factorial = [1 for i in range(n+1)]
        for i in range(2,n+1):
            factorial[i] = factorial[i-1]*i
        res = []
        depth = 0
        used = [0 for i in range(n)]
        nums = [str(i) for i in range(1,n+1)]

        def dfs(n, k, nums, path, res, used, depth):
            if len(res) < k:
                cnt = factorial[n-1]
                if depth == n:
                    res.append(path[:])
                for i in range(n):
                    if cnt<k:
                        k= k -cnt
                        continue
                    if used[i] == 0:
                        used[i] = 1
                        path.append(nums[i])
                        depth = depth + 1
                        dfs(n, k,nums, path, res, used, depth)
                        used[i] = 0
                        path.pop()
                        depth = depth - 1

        dfs(n,k,nums,[],res,used,depth)
        result = "".join(res.pop())
        return result

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值