题目:给定数字n, 在{1,2,3...n}中任意组合成n位数(数字不重复),求第key小的位置上的组合数字是多少?
例如:给定数字n =3,可以得到所有的数字组合为{123,132,213,231,312,321},
那么第key=4位置上的数就是===》231
代码实现与理解: 1. 根据key得出各个位置上的数字----在剩余数字--中的位置(从小到大)
例如231, 2排在{2,3,1}的第2位(从小到大);3排在{1,3}的第2位(从小到大);
1排在{1} 的第1位(当剩余一位时,默认是1);所以---》[2,2,1]
2. 将[2,2,1]恢复成正常的数字==》231
/**
* 1-n 个任意数字组合中第key小的数字
*
* @param n
* @param key
*/
public String getTargetNumber(int n, int key) {
int a[] = new int[n];
int number[] = new int[n];
for (int i = 0; i < n; i++) {
number[i] = i + 1;
}
/**
* 根据 key值判断每个数字在剩余数字中的位置
*
* 例如: n= 3, key = 4 时, 结果为:231, 其中 中 2 在{1,2,3}中排在
* 第 2 位(大小排序,从小到大), 3 排在 {3,1}中的第 2 位(从小到大),
* 1 为最后一位,所以排在{1}中的第1位
* 所以根据key计算得出 key =4 时的排序为==>[2, 2, 1]
*
*/
for (int i = n; i >= 1; i--) {
int count = getCount(i - 1);
if (i == 1) {
// i 代表 数字位数,当剩下最后一位时,默认排序为1
a[i - 1] = 1;
} else {
int first = key / count; // 除法运算
int firstCache = key % count; // 取余运算
if (firstCache == 0) {
// 如果余数==0
a[i - 1] = first;
key = count;
} else {
// 如果余数 != 0
a[i - 1] = first + 1;
key = firstCache;
}
}
}
/**
* 将排序结果恢复成为正常的数字字符串
* 例如: [2,2,1] ===> 2,3,1---->"231"
* 注意number初始是有序的数组【1,2,3,。。。】,位数取决于n
*/
String value = "";
for (int i = n - 1; i >= 0; i--) {
int code = 0;
int count = 0;
while (code < n) {
if (number[code] == 0) {
code++;
continue;
}
if (++count == a[i]) {
break;
}
code++;
}
value = value + number[code];
number[code] = 0;
}
return value;
}