LeetCode 60 _ Permutation Sequence 置換序列
Description:
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 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.
- Given k will be between 1 and n! inclusive.
Example 1:
Input: n = 3, k = 3 Output: "213"
Example 2:
Input: n = 4, k = 9 Output: "2314"
Solution:
這道題讓我們求出由1, 2, ... n按大小順序排列組成的全排列中第k位的數
觀察題目中給出的例子,我們可以看到在n=3時,由1開頭的數共有2個,由後兩位互換位置得到,2與3相同
我們再觀察由1~4組成的全排列,當第一位為1時,有如下幾種情況:
“1234”
“1243”
“1324”
“1342”
“1423”
“1432”
一共有6種情況。
當第一位固定時,全部情況即為剩下的三個數(2.3.4)進行全排列的所有情況,而這三位數的排列實際上也可以分為固定第二位,再對第三、四位進行排列。
對三、四位排列共有2種情況,乘上第二位的3種情況(2.3.4),即為三位數的全排列總數。
由以上情況我們可以推斷出,剩下i位數所占的情況數為:i * (i-1) * ... * 1
解題的思路:根據題目給出的所需求的位數k以及每一位數的總情況數,依次獲得第1,2,...n位數
例如題目中給出的例子,n=4,k=9時,1,2,3,4開頭每個共有6種情況,6<k<12,可確定第一位為2。
再以第一位為2為基礎,查看它的所有情況,1,3,4開頭每個共2中情況,2<k‘<4,可確定第二位為3。
依次類推,得到最後結果。
有一點需要留意的時,題目中給出的k,為從1開始計算,因此如果需要在循環中使用,要先將k-1,才能得到正確答案。
Code:
public String getPermutation(int n, int k) { List<Integer> ori = new ArrayList<>(); //store the origin number int[] factorial = new int[n+1]; factorial[0] = 1; for (int i = 1; i <= n; i++){ ori.add(i); // produce the origin number factorial[i] = factorial[i-1]*i; // produce the factorial series } // produce the result StringBuilder res = new StringBuilder(); k = k -1; while (n > 0){ int index = k / factorial[n-1]; k -= index * factorial[n-1]; res.append(ori.get(index)); ori.remove(index); n--; } return String.valueOf(res); }
提交情況:
Runtime: 1 ms, faster than 100.00% of Java online submissions for Permutation Sequence.
Memory Usage: 36 MB, less than 100.00% of Java online submissions for Permutation Sequence.
這情況不禁讓我納悶了,難道計數壞了麽,怎麽最近這倆都是100%,100%?這個算法好像沒啥巧的……?
LeetCode 60 _ Permutation Sequence 置換序列