========坚持30天刷leetcode=====
题目链接:https://leetcode-cn.com/problems/permutation-sequence/
结果:
分析:
做算法题一个很核心的点就是看题目,【能否看懂题目】很大程度上跟你【是否看全了题目】有很大关系!!特别是【说明】,有助于我们快速理解题目。
本题的思路有受上一题的思路启发,所以一定要按分类去做题,才会理解更加深刻!!!
本题给出n和k,分别表示【数字的范围】和【第几个序列】,且数字排列组成的序列呈升序排列。每个数字a都有 (n-1)! 个以a开头的序列。
因此,很容易想出,用 k 整除 (n-1)! 得出的商,代表其位于以哪个数字开头的序列集合中,余数代表序列集合中的第几个序列 。这时要注意,当可以整除时(余数等于0),商比其他情况要大1。如: (n-1)!=3!=6
序号k | 序列(n=4) | 商 | 余数 |
1 | 1234 | 0 | 1 |
2 | 1324 | 0 | 2 |
3 | 1324 | 0 | 3 |
4 | 1342 | 0 | 4 |
5 | 1423 | 0 | 5 |
6 | 1432 | 1 | 0 |
7 | 2134 | 1 | 1 |
... | ... | ... | ... |
那么,当我们确定了第一个数字时,我们怎么确定剩下的数字的顺序呢?
这时,就可以借鉴递归的思想了。在以某个数字a为开头的序列集合中,去掉a后,序列仍保持升序排序,等价于n=n-1,k=余数的问题。故,
若确定第一个数字时的整除余数为0,则代表剩下的数字按降序排序;
若余数不为0,则代表在剩下的数字进行递归。
代码如下:
# 返回值为:字符串
nlist=[1]*10
for i in range(1,10):
nlist[i]=nlist[i-1]*i
class Solution:
def getPer(self, n, k,xlist):
if n==1 and k!=1:
return
if n==1 and k==1:
return str(xlist[n-1])
a,b=divmod(k,nlist[n-1])
if b==0:
tmp=''
for j in range(n-1,-1,-1):
if j!=a-1:
tmp+=str(xlist[j])
return(str(xlist[a-1])+tmp)
else:
xx=xlist.pop(a)
return(str(xx)+self.getPer(n-1,b,xlist))
def getPermutation(self, n, k):
xlist=[x for x in range(1,n+1)]
return self.getPer(n,k,xlist)