1. 程式人生 > >獲取1~n全排列從小到大排列的第k個值

獲取1~n全排列從小到大排列的第k個值

問題描述:

給出集合 [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(); } }