题目描述:
题解一:回溯 超时
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