LC60. 排列序列

count = ji[n - 1 - index]
这一句首先是选一个的时候的排列个数,之所以这样写因为第一轮也就是比如n=4, k=15
选1之后k=k-6. 选2之后 k= k -6 -6 。 在同一层每次减去的选择个数相同,因为剩余的数相同。
比如n=4时做第一个选择之后剩余的数都是3也就是都剩下6种排列
if count < k:
k -= count
continue
这三句表示在同一层时每次的count也就是剩下的选择的个数相同continue结束本次循环
index控制层数,index+1表示进入下一层
不back,直接剪枝了,所以backtrack函数后面直接return

class Solution(object):
    def getPermutation(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: str
        """
        vsd = [0]*(n+1)
        sol = []
        ji = [1]*(n+1)
        for i in range(2, n+1):
            ji[i] = ji[i-1] * i
        def backtrack(sol, ji, vsd, k, index):
            if len(sol) == n:
                return
            count = ji[n - 1 - index]
            for i in range(1, n+1):
                if vsd[i] == 1:
                    continue
                if count < k:
                    k -= count
                    continue
                sol.append(i)
                vsd[i] = 1
                backtrack(sol, ji, vsd, k, index+1)
                return
        backtrack(sol, ji, vsd, k, 0)
        return ''.join(str(x) for x in sol)

count = [1,1,2,6,24] n=4 k=9
i = 1 count=6 < k=9 k = k-count = 3 sol = [] vsd[1] = 0 i += 1 index=0(没出for循环) count[n-1-0] = 6
i = 2 count=6 > k=3 k=k=3不变 sol =[2] vsd[2] = 1 back index = 1 (回溯出for循环) count[n-1-1] = 2
i = 1 count=2 < k=3 k = k-count = 1 sol = [2] vsd[1] =0 i += 1 index= 1(没出for循环) count[n-1-1] = 2
i = 2 count=2 > k=1 k=k=1不变 sol = [2,1] vsd[2] =1 continue i+=1
i = 3 count=2 > k=1 k=k=1不变 sol = [2,3] vsd[3] =1 back index = 2(回溯出for循环) count[n-1-2] = 1
i = 1 count=1 = k=1 k=k=1不变 sol = [2,3,1] vsd[1] =1 back index = 3(回溯出for循环) count[n-1-3] = 1
i = 1 count=1 = k=1 k=k=1不变 sol = [2,3,1] vsd[1] =1 continue i+=1
i = 2 count=1 = k=1 k=k=1不变 sol = [2,3,1] vsd[2] =1 continue i+=1
i = 3 count=1 = k=1 k=k=1不变 sol = [2,3,1] vsd[3] =1 continue i+=1
i = 4 count=1 = k=1 k=k=1不变 sol = [2,3,1,4] vsd[4] =1 back len(sol) = n = 4 返回

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值