您的位置:首页 > 产品设计 > UI/UE

【LeetCode】60. Permutation Sequence

2017-05-22 12:53 323 查看

问题描述

https://leetcode.com/problems/permutation-sequence/#/description

he 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.

求n个数字组成的所有全排列字符串中的第k个字符串。

算法

因为只要求
1
个,所以可以按照全排列的规则,一个个数的求出每个位置的数字,而不需要将所有的全排列字符串列出来。

对于
n
个字符组成的字符串
{1,2,3,...,n}
,取第
k
个数时,首先可以求出第一个数,即
(k-1)/(n-1个数的排列个数)


比如
n=3,k=4
时,全排列组合为:

1
+
{2,3}
的全排列

2
+
{1,3}
的全排列

3
+
{1,2}
的全排列

我们可以首先求出目标排序的第一个数字,即
(k-1)/(两个数的排列数) = (k-1)/2 = 3/2 = 1
,下标从
0
开始,下标
1
表示的数就是
2


接下来,就是求出
{1,3}
全排列中排在第
k-2=2
个位置上的数,方法同
3
个字母时一样,求出结果后为
231


所以,可以一层一层的求出第
k
个顺序的字符串。

时间复杂度为
O(N)


一开始是以递归形式写的算法,相对容易理解,但速度慢,所以又写了循环版本的。

代码

循环版本

public String getPermutation(int n, int k) {
char[] nums = new char[]{'1','2','3','4','5','6','7','8','9'};
String tmp = "";
for(int i=0;i<n;i++) {
tmp += nums[i];
}
StringBuffer s = new StringBuffer(tmp);
String r = "";
while(k>0&&!s.toString().equals("")) {
// 计算 (n-1)的排列个数cnt
int cnt = 1, i = s.length()-1;
while(i > 1) {
cnt*=i;
i-=1;
}
int pos = (k-1)/cnt;
r += s.charAt(pos);
s = s.deleteCharAt(pos);
k -= pos * cnt;
}
return r;
}


递归版本

public String getPermutation1(int n, int k) {
char[] nums = new char[]{'1','2','3','4','5','6','7','8','9'};
String s = "";
for(int i=0;i<n;i++) {
s += nums[i];
}
return fun(new StringBuffer(s), k);
}

public String fun(StringBuffer s, int k) {
if(k<0 || s.toString().equals("")) return "";
int cnt = 1, tmp = s.length()-1;
while(tmp > 1) {
cnt*=tmp;
tmp-=1;
}
int pos = (k-1)/cnt;
return s.charAt(pos) + fun(s.deleteCharAt(pos), k - pos*cnt);
}


LeetCode解题代码仓库:https://github.com/zgljl2012/leetcode-java
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: