leetcode 60 第K个排列-康托展开

Leetcode分类解析:组合算法 Leetcode分类解析:组合算法所谓组合算法就是指:在解决一些算法问题时,需要产生输入数据的各种组合、排列、子集、分区等等,然后逐一确认每种是不是我们要的解。从广义上来说,组合算法可以包罗万象,甚至排序、各种搜索算法都可以算进去。最近读《The Algorithm Design Manual》时了解到这种归类,上网一查,甚至有专门的书籍讲解,而且Knuth的巨著TAOCP的第四卷就叫组合算法,看来 阅读详情

leetcode 60 第K个排列

1.题目描述

给出集合 [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”

2.解题方法

1.回溯法+减枝

​ 思路分析:

​ 采用DFS深度优先遍历,每层从小到达选择一个数字,利用

​ visited数组记录每个数字的访问情况 ,当递归深度超出数组长度

​ 时,找到一种排列组合,序号+1,当前结果序号和目标序号k相同时,

​ 找到结果,设置全局变量退出其他递归函数。

​ 时间复杂度:O(n!)

​ 空间复杂度:

​ ps:回溯法的时间复杂度过高,会导致超时错误。

2.逆康托法

​ 思路分析:

​ 采用递归的思路,在每一位上确定一个数字,每次确定数字后,

​ 可形成(n-1)!种排列。

​ k从0开始,

​ 确定第一位:

​ group = k / (n-1)!, 所以查询结果在组号为group的组中

​ k = k - group * (n-1)!,更新查询的序号.

​ 例如:

​ [1,2,3,4], k = 15, n=4

​ group = up(15 / (3)!) = 3 , 第一位为nums[3-1] = 3,在第三组中

​ k = 15 % 3! = 3

​ 确定第二位:

​ [1,2,4]

​ group = up(3 / (2)!) = 2 , 第二位为nums[2-1] = 2,在第二组中

​ k = 3 % 2 = 1

​ 确定第三位:

​ [1,4]

​ group = up(1 / (1)!) = 1 , 第二位为nums[1-1] = 1,在第一组中

​ k = 1 - ((1 / (1)!)*(1!) = 0

​ 确定第四位:

​ [4]

​ 因为k=0,此时最后一位为nums[0]

​ 1—> (n-1)!

​ 2—> (n-1)!

​ 3—> 1 —> (n-2)!

​ 2 —> 2,1,4 —>(n-3)!

​ 2,4,1

​ 4 —> (n-2)!

​ 4—> (n-1)!

3.代码

import math
class Solution:
    def getPermutation(self, n: int, k: int) -> str:
        res = ""
        #候选数组
        nums = [ i+1 for i in range(n)]
        #求阶乘数组
        facts = [ 1 for i in range(n)]
        fact = 1
        for i in range(n):
            fact *= nums[i]
            facts[i] = fact
        N = n-1
        for i in range(n-1):
            #向上取整求组号,即当前候选数组的数字序号
            group = math.ceil(k/facts[N-1])
            res = res + str(nums[group-1])
            nums.pop(group-1)
            k = k % facts[N-1]
            N = N - 1
        #只剩下一位时,组数一定为1.
        res = res + str(nums[0])
        return res

4.康托展开

​ 康托展开完成了一个全排列到一个自然数的双射,即给出一个排列结果,可以找出此结果是全排列集合中的第几个。反之给出第几个,可以求出全排列的对应排列结果。

​ 本质是计算当前排列在由小到大全排列中的顺序。

​ 具体公式如下:

img

​ img表示原数的第i位在当前未出现的元素中是排在第几个(第几组),即比ai小的数字生成的全排列都不考虑,它们的全排列数量= 组数(比ai小的未选数字数目)* 每组元素个数(阶乘).

​ 例如:

在5个数的排列组合中,计算 34152的康托展开值。

​ 首位是3,则小于3的数有两个,为1和2,,则首位小于3的所有排列组合为
​ 第二位是4,由于第一位小于4,1、2、3中一定会有1个充当第一位,所以排在4之下的只剩2个,所以其实计算的是在第二位之后小于4的个数。因此。
​ 第三位是1,则在其之后小于1的数有0个,所以。
​ 第四位是5,则在其之后小于5的数有1个,为2,所以。
​ 最后一位就不用计算,因为在它之后已经没有数了,所以固定为0
根据公式:

所以比34152小的组合有61个,即34152是排第62。

​ 代码如下:

def kangtuozhankai(nums):
    #  k = a[n]*(n-1)! + a[n-1]*(n-2)! + a[1]*0!
    #  a[n] 表示小于当前位数字的个数
    n = len(nums)
    fact = 1
    facts = [ 1 for i in range(n+1)]
    for i in range(1,n+1):
        fact *= i
        facts[i] = fact

    result = 0
    for i in range(n):
        sum = 0
        for j in range(i+1,n):
            if nums[j]<nums[i]:
                sum += 1
        result += sum * facts[n-1-i]
    return result+1
LeetCode:60 第k个排列 全排列与康托展开 给出集合 [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... 阅读详情

相关推荐

字节尿性,康托展开求第K个排列!

今天是小浩算法“365刷题计划” 第 109 天。继续为大家讲解 leetcode 第 60 题,是一道中等难度的题目。排列类别的问题主要就两个,一个是全排列:小白真能看一篇文章就学会...

Google大神 345

康托展开及逆康托展开 + leetcode60. 排列序列

康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的。 康托展开: X=an(n−1)!+an−1(n−2)!+...+a1∗0!X = a_n(n-1)! + a_{n-1}(n-2)! +... + a_1*0!X=an​(n−1)!+an−1​(n−2)!+...+a1​∗0! 其中,ai为整数,且0≤ai<i,1≤i≤n其中,a_i为整数,且0 \leq a_i \lt i,1 \leq i \leq.

Dave_lzw的博客 562

Unity 调用安卓内部安装apk

一、申请权限 应用内安装其他应用的权限属于特殊权限,需要在特殊申请。 Uri packageURI = Uri.parse("package:" + mContext.getPackageName()); Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI); startA...

BDDNH的博客 1239

排列序数-康托展开式

题目: X星系的某次考古活动发现了史前智能痕迹。 这是一些用来计数的符号,经过分析它的计数规律如下: (为了表示方便,我们把这些奇怪的符号用a~q代替) abcdefghijklmnopq 表示0 abcdefghijklmnoqp 表示1 abcdefghijklmnpoq 表示2 abcdefghijklmnpqo 表示3 abcdefghijklmnqop 表示4

南方的孩子的博客 1166

Petalinux 2021.2 下 Qt组件编译报错?手把手教你修改bb文件搞定qt3d/qtquickcontrols2

本文详细解析了Petalinux 2021.2环境下Qt组件(如qt3d、qtquickcontrols2)编译报错的解决方案。通过修改bb文件或使用bbappend文件覆盖,有效解决`petalinux-build --sdk`命令执行时的源码获取失败或哈希校验不匹配问题,并提供验证与调试技巧,帮助开发者快速修复构建流程中断问题。

weixin_29188997的博客 216

【Chisel】2.4 时序逻辑

2.4 时序逻辑@[TOC](2.4 时序逻辑)前言寄存器(`Reg`)实例Chisel的状态函数实例2 RegNext实例3 RegInit移位器附录 显式的时钟信号和复位信号 前言 没有状态机的逻辑电路是不完整的,没有状态机的逻辑电路是不完整的,没有状态机的逻辑电路是不完整的,重要的事情说三遍。 这一节我们将要学习Chisel中的时序逻辑。在最后我们会实现一个移位器。 这里你需要知道的是,前面的这几节实际上都是对Chisel的基础语法的学习,它并不会给你带来很大的“惊喜”。Chisel真正的作用是把电路

快乐学习小猪猪的博客 843

第k个全排列(前缀法)

1.在控制台输入一个字符串,字符串长度小于等于12,并且输入一个数字n,求出字典序的第n个全排列 2.我们可以求出全部的全排列之后排序后输出第k个全排列,但是这样会非常浪费时间和空间,这里使用另外的一种方法,那就是前缀法求解第k个全排列 从头开始扫描字符串,假如当前字符没有出现,那么把这个字符加入到字符串中,假如以ABC为例,那么具体的前缀的形成过程如下: 从ABC调用完返回到上一层AB...

二哈 1751

AutoLISP 学习 (一)

AutoLISP基本语法结构、语法 以括号组成表达式,左右括号一定要成对,单、双引号也要成对,例如: (defun c:hello() (princ "\nHello world!") (prin1) ) 表达式格式:(函数名 操作数 操作数 …),例如: (setq p1 (list 0 0)) (setq p2 (list 10 10)) (setq p3 (list 20 20)) ;;; CAD中画直线,经过p1 p2 p3 (command "LINE" p1 p2 p3 ""

m0_54575622的博客 2122

leetcode 60. 第k个排列 康托展开

库函数 algorithm里面的next_permutation 效率不高 #include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; class Solution { public: string ge...

DUT_LYH 407

Android手机本地语音转文字实战:用FunASR+ONNX Runtime打造离线ASR应用(附模型下载)

本文详细介绍了如何在Android应用中集成FunASR和ONNX Runtime,构建高性能的离线语音识别系统。通过模型选择、工程化集成和性能调优等实战技巧,开发者可以实现本地语音转文字功能,有效保护用户隐私并提升响应速度。

weixin_29046611的博客 266

华为OD机考双机位C卷 - 信道分配(Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 信道分配

算法大师! 453

LeetCode 60. 第k个排列(回溯 & 康托展开)

文章目录1. 题目2. 解题2.1 回溯2.2 数学-康托展开 1. 题目 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: “123” “132” “213” “231” “312” “321” 给定 n 和 k,返回第 k 个排列。 说明: 给定 n 的范围是 [1, 9]。 给定 k 的范围是[1,...

Michael是个半路程序员 1280

大模型——CoPaw:阿里云通义推出的个人智能体工作台,让 AI 助理真正落地

阿里云通义实验室于2026年2月发布CoPaw个人智能助理,采用"本地+云端"双部署模式,支持多平台接入和技能扩展。该产品基于AgentScope多智能体生态构建,具备极简部署、长期记忆系统和灵活的技能插件体系三大核心特性。用户可通过简单命令快速安装,并通过记忆文件系统实现个性化交互体验。CoPaw还支持钉钉、飞书等主流平台接入,并开源了模块化架构,允许本地模型接入。技术架构采用多频道对话网关与可插拔Skills系统,为用户提供真正的AI助理服务体验。

2132

leetcode60. 第k个排列(康托展开/康托逆展开)

康托展开 52413 -> 4*4!+1*3!+2*2!+0*1!+0*0!=106 106+1=107 康托逆展开 1 2 3 4 5 1 1! 2! 3! 4! 5! 107 107-1=106 106 106/4!=4....10 1 2 3 4 5 -> 5 10 10/3!=1....4 1

weixin_42750434的博客 209

《QT+PCL》点云的点选与框选

【代码】《QT+PCL》点云的点选与框选。

阁楼 3602

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

[回溯][康托展开法]leetcode60:第k个排列(medium)

题目: 题解: 题解1:回溯法 本题自然而然地想到用回溯法解决,然而k值过大时,导致超时了,所以使用解法2的数学方法。 题解2:康托展开 康托展开是一个全排列到一个自然数的双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的。 对于n=3,k=3,我们将k减1(k--)表示k之前有k-1个排列,然后用2 / (3-1)! =1 余...

algsup 495

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

结合力扣题目:第k个排列,学习康托展开和逆康托展开

结合力扣第60题,第k个排列,进行康托展开和逆康托展开的学习。 题目描述:给出集合[1,2,…,n],其所有元素有n!种排列,按大小排列出所有情况,并一一标记,当n=3时,排列如下: “123” “132” “213” “231” “312” “321” 给定n和k,返回第k个排列 如n=3,k=3 则返回"213" 讲述康托编码之前,需要先学习一下康托展开,康托展开是一个全排列到自然数的一个双...

Mr_LHS的博客 400

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

关于康托展开和逆康托展开详解,及python代码

在LeetCode上有这样一道题: 60. 第k个排列 给出集合 [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 输出:

weixin_43786241的博客 1152

LeetCode 60. 排列序列【数学,逆康托展开】困难

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。。

memcpy0的博客 1525

【LeetCode】60. 排列序列

文章摘要 题目要求找出集合[1,2,...,n]的第k个字典序排列,避免暴力枚举。采用康托展开逆运算,通过阶乘分组定位每一位数字: 数学原理:每位选择对应(n-1)!个排列,通过k/(n-1)!确定当前数字索引,更新k=k%(n-1)!并递归处理剩余位。 算法优化:预计算阶乘表,转换为0-based索引,使用贪心选择数字,时间O(n²),空间O(n)。 示例:n=4,k=9,计算得排列"2314"。 对比:优于回溯法(O(kn))和字典序法(O(kn²)),是数学与算法结合的经典问题。

qq_32019341的博客 1329

leetcode#60 排列序列

leetcode#60 排列序列 题目: 给出两个数n,k,求1~n的第k个全排列(字典序)。 思路:逆康托展开 康托展开 给个排列问是第几个。 先给出结论:康托展开的结果为ans=A[0] * (n-1)!+A[1] * (n-2)!+A[2]*(n-3)!+…。== 其中A[i]代表 位于位置i后面的数小于A[i]值的个数,然后乘上后面的位数的阶乘。 不难理解,设序列p=abcdefg,那么对任意比p小的数列,一定存在前i位与p相同第i位比i小,后i位随意排列。因此,对于任意i,满足的条件数就是后面比i

weixin_48673014的博客 348

LeetCode-60. Permutation Sequence [C++][Java]

The set[1, 2, 3, ...,n]contains a total ofn!unique permutations. Givennandk, return thekthpermutation sequenc

贫道绝缘子的博客 457

LeetCode:60. Permutation Sequence,n全排列的第k个子列

LeetCode:60. Permutation Sequence,n全排列的第k个子列 : 题目: LeetCode:60. Permutation Sequence 描述: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the perm...

dbb191379的博客 226

Permutation Sequence

leetcode第60题,全排列的变种,要求找出n个数字全排列后按字典序的第k个数字。 第一种直观思路,直接生成n个数字的全排列,然后找到第k个就可以了,使用回溯,可以顺理成章地生成按字典序排列的全排列数字,顺序是不用太过关心的,但是这个方法跑不过大数据,因为复杂度太高。 def getPermutation(n, k): visit = [False] * 10 def d

恒河沙无数 338

康托展开和康托逆展开解决第K个排列问题

康托展开和康托逆展开解决第K个排列问题集合{1,2,3,…,n}包含了 n!种不同的排列,将这n!种排列从小到大进行排序,某个排列为第K 个, 求K时,使用康托展开,已知K求对应的排列时,使用康托逆展开。康托展开对于某个排列 a1, a2, a3, .. , an ,将其存入数组s{a1,a2,a3,…,an} 求它在n!个排列中的位置k, 用RLi表示ai后面比ai小的数的个数,Ri表示ai后面

lss_csdn的博客 510

leetcode-第k个排列-康托展开和康托逆展开

Leetcode-第60题,分类在回溯算法中,但是回溯并不是最佳解,甚至会超时。 乍一眼看,这又是一个类似于全排列的回溯题,第一思路是又使用回溯法递归出全排列的所有情况列一个表,然后根据k来找到第k个排列。 很遗憾的是这种方法,百分之百超时,效率太低,即便是添加了一些到达k就返回的剪枝,效率也很难令人满意。 事实上,使用纯数学的方法才是这题的解法,我们只想要第k个排列,不需要无谓的全盘列出。 题...

weixin_40710708的博客 418
上一篇: leetcode 12 整数转罗马数字
下一篇: Redis快速入门
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值