給出集合 [1,2,3,…,n],其全部元素共有 n! 種排列。git
按大小順序列出全部排列狀況,並一一標記,當 n = 3 時, 全部排列以下:github
1. "123" 2. "132" 3. "213" 4. "231" 5. "312" 6. "321"
給定 n 和 k,返回第 k 個排列。segmentfault
說明:app
示例 1:ui
輸入: n = 3, k = 3 輸出: "213"
示例 2:spa
輸入: n = 4, k = 9 輸出: "2314"
按照題目所描述的,其實就是按照排列規律,找出相應的數字。code
每一位上能夠存在的可能數字範圍逐漸減小,所以咱們須要記錄一下當前用過哪些數字
。內存
每一位上前綴數字最終對應的可能性也是一個全排列,好比 n 爲4時,當第1位定下來一個數字,其對應的全部數字組合有 3!,當第2位定下來後,其對應的數字組合就是2!。當你確認的數字越多,其組合也越少。get
直接上代碼:博客
class Solution { // 當前數字是否用過,默認爲false,表明沒有用過 boolean[] used; public String getPermutation(int n, int k) { used = new boolean[n]; int all = 1; for (int i = n - 1; i > 1; i--) { all *= i; } StringBuilder sb = dfs(n, all, k); return sb.toString(); } /** * n:當前還剩幾個數字沒有添加 * all:爲了計算出當前數字屬於第幾組,例如n等於5時,all是4!,這樣k/n就知道是第幾組了 * k:所求結果是當前組的第幾個 */ public StringBuilder dfs(int n, int all, int k) { // 組內偏移量 int offset = k % all; // 當前是第幾組 int groupIndex = k / all + (offset == 0 ? 0 : 1); // 在當前沒有被訪問過的數字裏,找第groupIndex個數字 int i = 0; for (; i < used.length && groupIndex > 0; i++) { if (!used[i]) { groupIndex--; } } // 用當前數字 StringBuilder result = new StringBuilder().append(i); // 標記當前數字已經用過 used[i - 1] = true; // 說明是最後一個數字 if (n == 1) { return result; } // 確認一位數字後,其對應的可能性就在減小 return result.append(dfs(n - 1, all / (n - 1), (offset == 0 ? all : offset))); } }
提交OK,執行用時:2ms
,內存消耗:34.4MB
。
以上就是這道題目個人解答過程了,不知道你們是否理解了。這道題應該主要就是找規律了,確認好邊界狀況就應該沒什麼問題。
有興趣的話能夠訪問個人博客或者關注個人公衆號、頭條號,說不定會有意外的驚喜。
公衆號:健程之道