天天看點

Permutation Sequence

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.

Note: Given n will be between 1 and 9 inclusive.

分析

這道題其實有很強的規律可循。首先,n個元素的排列總數是n!。在下面的分析中,讓k的範圍是0 <= k < n!。(題目代碼實際上是1<=k<=n!)

可以看到一個規律,就是這n!個排列中,第一位的元素總是(n-1)!一組出現的,也就說如果p = k / (n-1)!,那麼排列的最開始一個元素一定是arr[p]。

這個規律可以類推下去,在剩餘的n-1個元素中逐漸挑選出第二個,第三個,...,到第n個元素。程式就結束。

1. 建一個數組存階乘,另一個數組存通路過的節點

2. 從n-1到0履歷for-loop,其中建一個while-loop, 如果k大于對應正在周遊的i的階乘,把k減小i的階乘

3. 減小k的同時,增加tmp的值,這個while-loop結束條件是k小于i的對應階乘

4. 接下來,履歷一個for-loop,從0到n-1, 如果目前值小于對應的tmp,并且已被通路過,那麼tmp繼續加一

5. 把tmp的值加到stringbuilder後面,标記tmp對應的位數為已通路,進入下一輪大循環

1 public class Solution {
 2     public String getPermutation(int n, int k) {
 3         // Start typing your Java solution below
 4         // DO NOT write main() function
 5         boolean[] visited = new boolean[n];
 6         int[] factor = new int[n];
 7         factor[0] = 1;
 8         for(int i=1; i<n; i++)
 9             factor[i] = factor[i-1]*i;
10         StringBuilder sb = new StringBuilder();
11             
12         for(int i=n-1; i>=0; i--){
13             int tmp = 1;
14             while(k > factor[i]){
15                 tmp++;
16                 k -= factor[i];
17             }
18             for(int j=0; j<n; j++)
19                 if(j+1<=tmp && visited[j])
20                     tmp++;
21             sb.append(tmp);
22             visited[tmp-1] = true;
23         }
24         
25         return sb.toString();
26     }
27 }