作者:disappearedgod
时间:2014-8-13
题目
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.
解法
思路
1.String & StringBuffer & StringBuilder
String是一个对象。
StringBuffer 和 StringBuilder的最大区别在于线程问题。StringBuffer是线程不安全,而StringBuilder是线程安全的。
StringBuffer效率高(HashMap>HashTable)。
2.解题思路
思路借鉴于一个博客,他也是引入的,只是源出处我打不开了。并且他写的代码是不能通过的。(Wrong Answer)但是思路是对的。
【http://blog.youkuaiyun.com/chen895281773/article/details/12357703】
这道题自己思考得到了一个模糊的思路,而实际上这个问题已经有了很好的理论研究与证明,具体可以参考链接1
这里通过一个例子来说明本实现中的思路:
假设集合为[1,2,3,4],求出第6个组合。
第6个组合对应的下标为5(下标从0开始),我们首先求出5所对应的lehmer码(lehmer code的解释参考链接1):
5/3! = 0 余5
5/2! = 2 余1
1/1! = 1 余0
0 (lehmer code最后一位总为0)
所以所求lehmer码为0210
这里通过一个例子来说明本实现中的思路:
假设集合为[1,2,3,4],求出第6个组合。
第6个组合对应的下标为5(下标从0开始),我们首先求出5所对应的lehmer码(lehmer code的解释参考链接1):
5/3! = 0 余5
5/2! = 2 余1
1/1! = 1 余0
0 (lehmer code最后一位总为0)
所以所求lehmer码为0210
3.字典序
这道题是一道排列题,具体的方法就是字典序。借鉴的博客中一些来自wikipedia。
字典序其实是在找一个交租lehmer Code的东西,这个是数学中证明过的东西。
可以有下面计算下一个排列的算法:
设P是1~n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn
1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1} 2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=max{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者) 3)对换pi,pk 4)再将pj+1......pk-1pkpk+1......pn倒转得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个排列。
证明

public class Solution {
public String getPermutation(int n, int k) {
StringBuffer sb = new StringBuffer();
StringBuffer ret = new StringBuffer();
if(n<2){
ret.append(n);
return ret.toString();
}
int temp =0;
for(int i =0 ; i < n ; i++){
sb.append(i+1);
}
int[] factor = new int[n];
factor[0] =1;
for(int i = 1 ; i < n ; i ++){
factor[i] = factor[i-1] * i;
}
k--;
for(int i = n-1;i>=0;i--){
temp = k / factor[i];
k = k % factor[i];
ret.append(sb.charAt(temp));
sb.deleteCharAt(temp);
}
return ret.toString();
}
}