【经典算法题】排列序列

Leetcode 0060 排列序列

题目描述:Leetcode 0060 排列序列

分析

  • 本题的考点:数学

  • 对于c++而言,可以使用next_permutation,计算量为n!×nn! \times nn!×n,最大为9!×9=3,265,9209! \times 9 = 3,265,9209!×9=3,265,920,可以通过,考试肯定用这种做法。

  • 下面讲解另一种做法:计数法

  • 对于n,我们要求第k大的小的数,我们可以依次考虑1~n这些位置应该放入哪个数字,从第一个位置开始考虑,如果放入1的话,则后面还有n-1个位置,一共有(n-1)!种方案,比较k(n-1)!的大小,如果k > (n-1)!,说明第k小的数必定不可能是1开头的数字。之后将k更新为k-(n-1)!,考虑第一个位置放入2,直到找到第一个位置放置的数字,使得k≤(n−1)!k \le (n-1)!k≤(n−1)!,则该数字就是第一位应该放的数字。

  • 依次考虑后面2~n位应该放入哪些数字。注意已经用过的数字不能再使用,需要使用一个数组st进行判重。

  • 如下图,是n=4, k=10对应的情况:

代码

  • C++
class Solution {public:string getPermutation(int n, int k) {string res;for (int i = 1; i <= n; i++) res += to_string(i);for (int i = 0; i < k - 1; i++) {next_permutation(res.begin(), res.end());}return res;}
};
class Solution {public:string getPermutation(int n, int k) {vector<int> fact(10, 1);  // 阶乘for (int i = 2; i < 10; i++) fact[i] = fact[i - 1] * i;string res;vector<bool> st(10);  // 判重数组for (int i = 0; i < n; i++)  // 枚举每个位置, 即res[i]应该填入哪个数字for (int j = 1; j <= n; j++)  // 枚举所有数字if (!st[j]) {  // j还没被使用过if (fact[n - 1 - i] < k)   // 说明res[i]不应该放入jk -= fact[n - 1 - i];else {res += to_string(j);st[j] = true;break;  // 表示res[i]已经填入了正确的数字}}return res;}
};
  • Java
class Solution {public String getPermutation(int n, int k) {int[] fact = new int[n];fact[0] = 1;for (int i = 1; i < n; i++) fact[i] = fact[i - 1] * i;StringBuilder sb = new StringBuilder();boolean[] st = new boolean[10];for (int i = 0; i < n; i++)for (int j = 1; j <= n; j++)if (!st[j]) {if (fact[n - 1 - i] < k) k -= fact[n - 1 - i];else {sb.append((char)('0' + j));st[j] = true;break;}}return sb.toString();}
}
  • Python
class Solution:def getPermutation(self, n: int, k: int) -> str:fact = [1 for _ in range(n)]for i in range(1, n):fact[i] = fact[i - 1] * ires = ""st = [False for _ in range(10)]for i in range(n):for j in range(1, n + 1):if not st[j]:if fact[n - 1 - i] < k:k -= fact[n - 1 - i]else:res += chr(j + ord('0'))st[j] = Truebreakreturn res

时空复杂度分析

  • 时间复杂度:O(n2)O(n^2)O(n2)。计数法中有两重循环。
  • 空间复杂度:O(n)O(n)O(n)。

【经典算法题】排列序列相关推荐

  1. C++经典算法题-排列组合

    27.Algorithm Gossip: 排列组合 说明 将一组数字.字母或符号进行排列,以得到不同的组合顺序,例如1 2 3这三个数的排列组合有: 1 2 3.1 3 2.2 1 3.2 3 1.3 ...

  2. python全排序算法题_Python的100道经典算法题(1)

    按照c语言的100道经典算法题,自己原创写的,就得是自己的练习题了 [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 程序分析:可填在百位.十位.个位的数 ...

  3. 经典算法题每日演练——第六题 协同推荐SlopeOne 算法

    原文:经典算法题每日演练--第六题 协同推荐SlopeOne 算法 相信大家对如下的Category都很熟悉,很多网站都有类似如下的功能,"商品推荐","猜你喜欢&quo ...

  4. 经典算法题每日演练——第二十二题 奇偶排序

    原文:经典算法题每日演练--第二十二题 奇偶排序 这个专题因为各种原因好久没有继续下去了,MM吧...你懂的,嘿嘿,不过还得继续写下去,好长时间不写,有些东西有点生疏了, 这篇就从简单一点的一个&qu ...

  5. 经典算法题每日演练——第十九题 双端队列

    经典算法题每日演练--第十九题 双端队列 原文:经典算法题每日演练--第十九题 双端队列 话说大学的时候老师说妹子比工作重要~,工作可以再换,妹子这个...所以...这两个月也就一直忙着Fall in ...

  6. 经典算法题每日演练——第十题 树状数组

    原文:经典算法题每日演练--第十题 树状数组 有一种数据结构是神奇的,神秘的,它展现了位运算与数组结合的神奇魅力,太牛逼的,它就是树状数组,这种数据结构不是神人是发现不了的. 一:概序 假如我现在有个 ...

  7. 经典算法题每日演练——第一题 百钱买百鸡

    经典算法题每日演练--第一题 百钱买百鸡 原文:经典算法题每日演练--第一题 百钱买百鸡 百钱买百鸡的问题算是一套非常经典的不定方程的问题,题目很简单:公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱, ...

  8. java经典100例算法题_10道java经典算法题,每一题都能帮你提升java水平!

    JAVA经典算法题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析:兔子 ...

  9. 经典算法题每日演练——第七题 KMP算法

    原文:经典算法题每日演练--第七题 KMP算法 在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的, 确实kmp算法还是有点饶人的,如果说红黑树 ...

  10. 每日经典算法题(十六) 九九乘法表

    每日经典算法题(十六) 九九乘法表 九九乘法表:Multiplication Table 99 题目 输出 9 * 9 口诀 程序分析 分行与列考虑,共9行9列,i 控制行,j 控制列 思路 非常经典 ...

最新文章

  1. 史上最浅显易懂的Git教程!
  2. Analysis Services基础知识——深入SQL Server 2008
  3. 一、什么是hadoop?
  4. 正则表达式超级生成工具 Regulator
  5. cogs62 [HNOI2004] 宠物收养所
  6. sql数据表改为自动递增显示与其他表关联_MySQL萌新第一季 第四话-数据表的基本操作...
  7. linux资源限制函数getrlimit,setrlimit(转载)【转】
  8. 怎么单选_听力三个选项都出的单选怎么破?| 附今日听力S1S2及听力原文
  9. vue学习笔记-12-计算属性
  10. word宏加密的破解
  11. 怎么样正确卸载Flash Player插件
  12. GPU共享内存:pycuda使用教程
  13. Windows Server 2016 实现跨域、跨林之间的访问
  14. 从oracle到mysql模型转换的自动化实现
  15. 律师向公安部举报称微软黑屏是最大***行为
  16. nginx的location匹配字段后斜杠的作用
  17. spring mvc前端验证代码生成器
  18. 区块链的共识机制是什么?
  19. java实现图片上传至本地
  20. discuz论坛部署及常见问题处理

热门文章

  1. Mac上的全局翻译利器 : Bob + PopClip
  2. 力扣-剑指offer所有题
  3. 测试驱动开发心得体会
  4. NSIS 注册DLL OCX
  5. iOS YYKit学习之YYText的使用
  6. matlab差分法解拉普拉斯方程,拉普拉斯方程有限差分法的MATLAB实现
  7. 理解OFDM技术原理
  8. Windows 7 SP1 语言包下载
  9. 服务器车牌识别系统,车牌识别系统数据库连接问世
  10. 数论学习-初等数论基础总览