獲取1~n全排列從小到大排列的第k個值
阿新 • • 發佈:2019-02-15
問題描述:
給出集合 [1,2,3,…,n],其所有元素共有 n! 種排列。
按大小順序列出所有排列情況,並一一標記,
可得到如下序列 (例如, n = 3):“123”
“132”
“213”
“231”
“312”
“321”
給定 n 和 k,返回第 k 個排列序列。注意:n 介於1到9之間(包括9)。
思路:
我的思路是每次求出k /(n-1)!,通過這樣來判斷本次的第一個數字是什麼。
比如說 n = 3,k = 4,那麼1位數字開頭的可能有2!種,而4/2 =2,證明我需要的數字是以2開頭。然後在2開頭的排列組合中找到第2個數字,這個尋找過程與上一步類似,每次查詢時序注意已經經使用過的數字不能再使用。(本人語言表達能力不好,可能程式碼更好看懂些)
Java實現如下:
class Solution {
public String getPermutation(int n, int k) {
int[] arr = new int[]{1,1,2,6,24,120,720,5040,40320,363880};//記錄0-9的階乘
boolean[] isUsed = new boolean[10];//標記已經使用過的數字
StringBuilder sBuilder = new StringBuilder();//答案字串
int index = n;//待確定的資料位置,可根據這個計算(index-1)!
int temp1 = 0;//臨時變數 記錄 k/arr[index-1]
int temp2 = 0;//臨時變數 記錄 k%arr[index-1]
while(k>0&&index>0){
//System.out.println(k+" "+index);
temp1 = k/arr[index-1];
temp2 = k%arr[index-1];
//根據temp1和temp2更新k值,然後計算出當前是第temp1個未被使用的數字
if (temp2!=0){
temp1=temp1+1;
k = temp2;
}else{
k = arr[index-1];
}
//找到第temp1個未使用的數字
int count = 0;
for(int i = 1;i<= n;i++){
if(isUsed[i]==false){
count++;
if(count == temp1){
sBuilder.append(i);
isUsed[i] = true;
break;
}
}
}
index--;
}
return sBuilder.toString();
}
}