题目

The set [1,2,3,…,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order,

We get the following sequence (ie, for n = 3):

“123”

“132”

“213”

“231”

“312”

“321”

Given n and k, return the kth permutation sequence.

Note: Given n will be between 1 and 9 inclusive.

分析

首先想到的是,采用STL库中的标准算法next_permutation(),寻找第k个排列即可,可是提交结果为Time Limited Exceed,显然,必须寻找更优算法。

借鉴了别人的思想,设计如下(原文博客):

数学解法

在n!个排列中,第一位的元素总是(n-1)!一组出现的,也就说如果p = k / (n-1)!,那么排列的最开始一个元素一定是nums[p]。

假设有n个元素,第K个permutation是

a1, a2, a3, ….. …, an

那么a1是哪一个数字呢?

那么这里,我们把a1去掉,那么剩下的permutation为

a2, a3, …. …. an, 共计n-1个元素。 n-1个元素共有(n-1)!组排列,那么这里就可以知道

设变量K1 = K

a1 = K1 / (n-1)!

同理,a2的值可以推导为

a2 = K2 / (n-2)!

K2 = K1 % (n-1)!

…….

a(n-1) = K(n-1) / 1!

K(n-1) = K(n-2) /2!

an = K(n-1)

STL标准算法实现(Time Limited Exceed)

class Solution {
public:
string getPermutation(int n, int k) {
if (n <= 0 || k <= 0 || k > factorial(n))
return ""; vector<int> v;
for (int i = 1; i <= n; i++)
v.push_back(i); int index = 1;
while (index < k && next_permutation(v.begin(), v.end()))
index++; string str = "";
for (int i = 0; i < n; i++)
str += IntToStr(v[i]);
str += '\0'; return str; } string IntToStr(int n)
{
string str = ""; while (n != 0)
{
str += (n % 10 + '0');
n /= 10;
} reverse(str.begin(), str.end()); return str;
} long factorial(int n)
{
if (n <= 1)
return 1;
else
return n * factorial(n - 1);
}
};

AC代码

class Solution {
public: string getPermutation(int n, int k) {
vector<int> nums(n); int pCount = 1;
for (int i = 0; i < n; ++i) {
nums[i] = i + 1;
pCount *= (i + 1);
} k--;
string res = "";
for (int i = 0; i < n; i++) {
pCount = pCount / (n - i);
int selected = k / pCount;
res += ('0' + nums[selected]); for (int j = selected; j < n - i - 1; j++)
nums[j] = nums[j + 1];
k = k % pCount;
}
return res;
} };

GitHub测试程序源码

LeetCode(60) Permutation Sequence的更多相关文章

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

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

  2. Leetcode(1)两数之和

    Leetcode(1)两数之和 [题目表述]: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标.你可以假设每种输入只会对应一 ...

  3. Leetcode(3)无重复字符的最长子串

    Leetcode(3)无重复字符的最长子串 [题目表述]: 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 第一种方法:暴力 执行用时:996 ms: 内存消耗:12.9MB 效果: ...

  4. Leetcode(8)字符串转换整数

    Leetcode(8)字符串转换整数 [题目表述]: 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我 ...

  5. Qt 学习之路 2(60):使用 DOM 处理 XML

    Qt 学习之路 2(60):使用 DOM 处理 XML  豆子  2013年8月3日  Qt 学习之路 2  9条评论 DOM 是由 W3C 提出的一种处理 XML 文档的标准接口.Qt 实现了 DO ...

  6. LeetCode(275)H-Index II

    题目 Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimi ...

  7. LeetCode(220) Contains Duplicate III

    题目 Given an array of integers, find out whether there are two distinct indices i and j in the array ...

  8. LeetCode(154) Find Minimum in Rotated Sorted Array II

    题目 Follow up for "Find Minimum in Rotated Sorted Array": What if duplicates are allowed? W ...

  9. LeetCode(122) Best Time to Buy and Sell Stock II

    题目 Say you have an array for which the ith element is the price of a given stock on day i. Design an ...

随机推荐

  1. bzoj1303[CQOI2008]中位数图 / 乱搞

    题目描述 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. 输入输出格式 输入格式: 第一行为两个正整数n和b,第二行为1 ...

  2. iOS导航栏NavigationBar的颜色,按钮和标题以及字体颜色

    首先,层级关系: leftBarButtonItem.rightBarButtonItem.title都是加在UINavigationItem上的,UINavigationItem再加在Navigat ...

  3. AutoCAD2012启动错误 1308 源文件未找到

    启动AutoCAD2012时,弹出错误1308,如图所示: 是何原因? 对CAD的运行有何影响?

  4. 安装11g 数据库

    出现问题解决: 1.首先确认下载的安装包完整性.2解压包的时候,按顺序解压,解压第一个包后,解压第二个包的时候,要把解压地址与解压第二包的地址要一样. 安装的时候,需要把两个压缩包都解压,并将目录wi ...

  5. 转-iOS开发系列--地图与定位

    来自: http://www.cnblogs.com/kenshincui/p/4125570.html#autoid-3-4-0 概览 现在很多社交.电商.团购应用都引入了地图和定位功能,似乎地图功 ...

  6. Webform 三级联动例子

    首先分别做三个下拉列表 <body> <form id="form1" runat="server"> <asp:DropDown ...

  7. 程序猿工具——svn

    一个项目的产生,都需要团队中的开发人员互相协作.它的简单,方便深深吸引了我. svn的使用,有2部分组成--svn服务器.svn客户端.svn服务器一般团队之间只要有一个安装就可以了. 在学习安装sv ...

  8. AJPFX总结在循环中break与continue的区别

    相信刚学编程的人很容易被break,continue这两个关键词搞混淆了,两者都有跳出循环的意思,但是他们到底有什么区别呢?其实很简单,break是结束整个循环体,continue是结束当前这一单次循 ...

  9. 《effective java》中文第2版 note

    ,第15条[66]: 为不可变类提供静态工厂, eg : Integer/BigInteger 使用了静态工厂缓存了一些常用的实例, 通常 Integer -128 ~ +127. BigIntege ...

  10. jQuery 几款比较棒的插件

    jQuery滚动监听插件Waypoints 博客分类: Javascript /Jquery / Bootstrap / Web   你是否希望当用户仅仅滚动滑条的时候,就能触发各种各样的动态效果呢? ...