问题描述:
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):
1、"123"
2、"132"
3、"213"
4、"231"
5、"312"
6、"321"
Given n and k, return the kth permutation sequence.
这道题大致的意思就是对1-n这n个数进行排列组合,按小的在前面\大的在后面的顺序来排列组合,然后取第k个排列组合的结果。就比如上面那个例子,n=3,k=5,那么结果返回“312”。
实际上这道题不难,它是从高位到低位每一位来选的。
首先将1-n个数存进一个numberList中,然后按位进行选数字。选数字是根据索引在numberList中选,而索引呢,则取决于k和n,具体公式为k / factorial[n-i]。拿到索引后就在numberList中选,然后在numberList删除这个数(选过了就不能再选了),然后将k进行修正,修正为在指定范围中的索引,再选下一位数字,直到所有位都选完,就搞定了。
其实说不太好说明白,大家可以在纸上写一下,举例子,就可以发现其中的规律,我就是这样推出来的。
上代码吧:
public String getPermutation(int n, int k) {
//用来存储每一个数对应的阶乘
int []factorial = new int[n];
//用来保存剩余的数,一个索引对应一个数
List<Integer> numberList = new ArrayList<>();
//用来储存结果
StringBuffer result = new StringBuffer();
//先将次序转换为相应的索引
k--;
factorial[0] = 1;
//计算阶乘并将1-n的数添加进list中
for(int i = 1; i < n; i++) {
factorial[i] = factorial[i-1] * i;
numberList.add(i);
}
numberList.add(n);
//每次循环决定一位数
for(int i = 1; i <= n; i++) {
//决定当前要取的这一位在numberList中的索引位置,实际上就是 k/(n-1)!
int index = k / factorial[n-i];
//添加进结果,并在numberList删除已经选过的数
result.append(String.valueOf(numberList.get(index)));
numberList.remove(index);
//将k修正为指定范围中的索引
k = k - index*factorial[n-i];
}
return result.toString();
}
谢谢大家观看我的博客。如果大家有不明白的地方,或者文中有出错的地方,欢迎大家指出,谢谢!