题目:给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
    "123"
    "132"
    "213"
    "231"
    "312"
    "321"
给定 n 和 k,返回第 k 个排列。
说明:给定 n 的范围是 [1, 9]。给定 k 的范围是[1,  n!]。

来源: https://leetcode-cn.com/problems/permutation-sequence/

法一:自己的代码    耗时很短,利用python自带的阶乘函数计算耗时会更短

思路:转化为一个纯数学的问题,关键是要把每种情况都考虑到,特别是除n!后是整数的情况,举例的时候就要把每种情况都枚举到,编程才不会出错

import math
class Solution:
def getPermutation(self, n: int, k: int):
# 自定义阶乘函数
def n_factorial(x):
if x == 0:
return 1
else:
return x * n_factorial(x-1)
nums = [i+1 for i in range(n)]
result = ''
while n > 0:
n = n - 1
# 通过观察数据可以看出,假如输入是(4,9),则说明以1开头的有3!个,以2开头的有3!个,
# 所以用9除以3的阶乘是1.5,1,5向上取整为2,即nums中的第二个数2是结果中的第一个数,
# 再用9减去6为3表示从2开始的组别中找第三个数,
res = k / n_factorial(n)
res_up = math.ceil(res)
# 注意这里向下取整必须是向上取整后减1,这是因为比如输入的是(4,6),则6除3!为1,1-1=0,所以不可直接向下取整
res_down = res_up - 1
k = k - res_down * n_factorial(n)
result = result + str(nums[res_up-1])
del nums[res_up-1]
print('-'* 20)
print('k', k)
# print(res)
print(res_up)
# print(res_down)
return result
if __name__ == "__main__":
duixiang = Solution()
a = duixiang.getPermutation(4,9)
print(a)

法二:自己的代码    利用回溯,但是超时,超时是因为没有用continue,每个分支都要检查一遍

class Solution:
def getPermutation(self, n: int, k: int):
nums = [i+1 for i in range(n)]
global count,result
count = 0
def backtrack(a='', nums=nums, ):
global count,result
# print('k',count)
if count == k:
return
if len(a) == n:
count += 1
# print('count', count)
if count == k:
result = a
# exit()
# return count
for i,j in enumerate(nums):
r = nums.copy()
del r[i]
# print('ttt',count)
# sign,result = backtrack(a+str(j), r)
backtrack(a+str(j), r)
backtrack()
return result

改进后的不会超时,注意这里return的用法,非常巧妙

class Solution:
def getPermutation(self, n: int, k: int):
nums = [i+1 for i in range(n)]
from1to9_factorial = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
def backtrack(a='', nums=nums,k = k ):
# 一旦满足条件立即逐层返回a,结束所有函数
if len(a) == n:
return a
t = from1to9_factorial[len(nums) - 1]
for i,j in enumerate(nums):
if k > t:
# 执行剪枝操作,如果大于t了,就结束本次循环
k = k - t
continue
# r中是下次for循环要遍历的数
r = nums.copy()
del r[i]
# 这里必须用return,避免了定义全局变量来解决问题
return backtrack(a+str(j), r, k)
return backtrack()
if __name__ == "__main__":
duixiang = Solution()
a = duixiang.getPermutation(4,10)
print(a)

60第K个排列的更多相关文章

  1. Java实现 LeetCode 60 第k个排列

    60. 第k个排列 给出集合 [1,2,3,-,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" &q ...

  2. LeetCode 60 第K个排列

    题目: 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" "13 ...

  3. LeetCode 60. 第k个排列(Permutation Sequence)

    题目描述 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" "1 ...

  4. 力扣60——第k个排列

    原题 给出集合 [1,2,3,-,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: 1. "123" 2. &qu ...

  5. 算法:60.第k个排列

    解答参考:https://blog.csdn.net/lqcsp/article/details/23322951 题目链接:https://leetcode-cn.com/problems/perm ...

  6. 代码题(45)— 下一个排列、第k个排列

    1.31. 下一个排列 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只 ...

  7. LeetCode:第K个排列【60】

    LeetCode:第K个排列[60] 题目描述 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: &quo ...

  8. LeetCode(60): 第k个排列

    Medium! 题目描述: 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" ...

  9. LeetCode 中级 - 第k个排列(60)

    可以用数学的方法来解, 因为数字都是从1开始的连续自然数, 排列出现的次序可以推 算出来, 对于n=4, k=15 找到k=15排列的过程: 1 + 对2,3,4的全排列 (3!个) 2 + 对1,3 ...

随机推荐

  1. Hibrenate实现根据实体类自动创建表或添加字段

    Hibernate支持自动建表,在开发阶段很方便,可以保证hbm与数据库表结构的自动同步. 实现: 在配置hibernate的配置文件中将hbm2ddl.auto设置为update,如:Xml代码&l ...

  2. maven 学习之路之二(1)

    上次我简单讲了maven的安装和构建生命周期. 这一篇博客我将用实际项目来分享下maven整个构建生命周期的具体使用: 这次我将用maven做一个自己写程序的一个模版程序. 自己实现一个简单的页面登录 ...

  3. 模拟赛小结:The 2019 China Collegiate Programming Contest Harbin Site

    比赛链接:传送门 上半场5题,下半场疯狂挂机,然后又是差一题金,万年银首也太难受了. (每次银首都会想起前队友的灵魂拷问:你们队练习的时候进金区的次数多不多啊?) Problem J. Justify ...

  4. flask实现文件的上传

    文件上传过程中,一定要进行文件大小的校验,如果用户上传文件过大,比如:100GB,所以一直在处理这个请求,别的请求进来就无法处理了,所以要限制上传文件的大小. flask中文件上传大小的校验 flas ...

  5. debug --- 使用Eclipse

    debug必知(快捷键若无效,有可能是与其它软件的快捷键发生冲突的原因) 1.F6  ——  单步执行代码,即顺序一行行地执行源码 2.F5  ——  跳入当前调用的函数的内部,即进入函数内部执行源码 ...

  6. Codeforces Round #593 (Div. 2) D. Alice and the Doll

    题目:http://codeforces.com/problemset/problem/1236/D思路:机器人只能按照→↓←↑这个规律移动,所以在当前方向能够前进的最远处即为界限,到达最远处右转,并 ...

  7. java 枚举的用法

    public enum StatisticTableEnum { DOC_BROWSE_STATISTIC("doc_browse_statistic"), DOC_LIB_BRO ...

  8. 洛谷P3402 可持久化并查集

    n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 说是可持久化并查集,实际上是 ...

  9. CSS选择器的权重与优先规

    我们把特殊性分为4个等级,每个等级代表一类选择器,每个等级的值为其所代表的选择器的个数乘以这一等级的权值,最后把所有等级的值相加得出选择器的特殊值. 4个等级的定义如下: 第一等:代表内联样式,如: ...

  10. mysql向redis导入数据

    数据库结构如下 如果是linux系统下,如此整备数据 SELECT CONCAT( "*10\r\n", '$', LENGTH(redis_cmd), '\r\n',redis_ ...