Leetcode做题日记:60. 第k个排列(PYTHON)

给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

"123"
"132"
"213"
"231"
"312"
"321"

给定 n 和 k,返回第 k 个排列。

说明:

给定 n 的范围是 [1, 9]。
给定 k 的范围是[1,  n!]。

示例 1:

输入: n = 3, k = 3
输出: “213”

示例 2:

输入: n = 4, k = 9
输出: “2314”
首先想到全排列,然后找到第k个排列:

	def npl(n,m,ans): #n是n个数字的列表
            if len(m)==len(n):#达到长度,加入全排列列表ans
                ans.append(m)
            else:
                for i in n:
                    if i not in m: #加入不重复的数字
                        npl(n,m+[i],ans) #递归
        pl=[]
        for i in range(1,n+1):
            pl.append(i)
        ans=[]
        npl(pl,[],ans)
        ans.sort() #先按从小到大是顺序排序
        A=ans[k-1]
        c=''
        for i in A: #返回是字符串
            c=c+str(i)
        return c

[9 199269]妥妥超时了
加一条回溯条件:

 	def npl(n,m,ans,k):
            
            if len(ans)==k:
                return

依旧超时,但是正确,表明递归的答案是按顺序返回的。所以程序不用加ans.sort()
第二次代码:用数学方法确定每次选择的数字,例如k=10,n=4,l=[1,2,3,4],10/3!=1,10%3!=4,所以取l[1]=2,第一个数字是2,更新k=10%3!=4,第二轮循环,l=[1,3,4],4/2!=2,4%2!=0,因此第二个数取l[2-1]=3,k=0,第三轮循环,l=[1,4], 0/1!=0,0%1!=0,第三个数取l[0]=1,同理,第四个数取4

python竟然没有计算阶乘的代码,只能自己写递归了。
因为返回一个字符串,所以这次不采用递归,使用while循环:

	def jc(n):
            if n==1 or n==0:
                return 1
            else:
                return n*jc(n-1)
        l=[]
        ans=''
        for i in range(1,n+1):#n=4,l=['1','2','3','4']
            l.append(str(i))  #方便返回字符串  
        
        while l :
            n1=len(l)-1#计算当前l中每个数字可以有多少种排列
                       #如l=[1,2,3],以1,2,3开头的数分别有两种排列
            n2=jc(n1)  #数学描述就是阶乘
            n3=k%n2    #计算余数,即下一轮的 k,
            n4=k/n2    #用来选择当前循环选择的数字
            if n3==0:  #判断是否处于某个数排列的最后一个
                n4=n4-1 #例[1,2,3],1有两种排列,k=2时,还是选择1开头
                        #所以n4要减1
            if k==1 : #若是第一个排列,直接返回列表值,可去,单纯为了加速
                for j in l:
                    ans=ans+j
                return ans
            else: #若是其他情况,取列表第n4个元素到ans,继续循环
                ans=ans+l[n4]
                k=n3
                l.pop(n4) #取过的元素删除
        return ans

32ms,排名24.5%

猜你喜欢

转载自blog.csdn.net/weixin_44033136/article/details/86639726