題目:
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):
"123"
"132"
"213"
"231"
"312"
"321"
Given n and k, return the kth permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
提示:這道題我一上來使用了backtracking的方法依次構造出排列數,當然結果不出所料的TLE了。實際上,仔細觀察這些數字,我們還是不難發現一些規律的。
假設有四位數字{1, 2, 3, 4},那么他們能夠產生的排列數是什么呢?
- 1 + {2, 3, 4}
- 2 + {1, 3, 4}
- 3 + {1, 2, 4}
- 4 + {1, 2, 3}
其實就是選定第一位數字后,其他剩下的數字進行排列組合,就能求出以該數字打頭的所有排列組合。想必已經能發現一些規律了,我們干脆再舉一個具體的例子,比如我們現在想要找第14個數,那么由於14 = 6 + 6 + 2。因此第一個數打頭的是3,然后再求{1, 2, 4}中第二個排列組合數,答案是"142"。所以最終答案就是"3142"啦。
這里有一些問題是需要我們注意的:
- 構造排列數從最高位開始,當選出一個數字后,就應當把這個數字erase掉,防止后面又出現;
- 我們所要求的第k個數需要在每次循環中減去對應的值;
- 注意程序中的數組是從0開始的,但題目的輸入是從1開始計數的。
代碼:
class Solution { public: string getPermutation(int n, int k) { vector<int> permutation(n + 1, 1); for (int i = 1; i <= n; ++i) { permutation[i] = permutation[i - 1] * i; } vector<char> digits = { '1', '2', '3', '4', '5', '6', '7', '8', '9' }; int num = n - 1; string res; while (num) { int t = (k - 1) / (permutation[num--]); k = k - t * permutation[num + 1]; res.push_back(digits[t]); digits.erase(digits.begin() + t); } res.push_back(digits[k - 1]); return res; } };