給出集合 [1,2,3,…,n],其全部元素共有 n! 種排列。java
按大小順序列出全部排列狀況,並一一標記,當 n = 3 時, 全部排列以下:python
給定 n 和 k,返回第 k 個排列。app
說明:性能
給定 n 的範圍是 [1, 9]。
給定 k 的範圍是[1, n!]。
示例 1:ui
輸入: n = 3, k = 3 輸出: "213"
示例 2:spa
輸入: n = 4, k = 9 輸出: "2314"
這道題還蠻有意思的,我首先一看,這不是backtrack的經典題目嗎? backtrack的剪枝能夠參看相關文章中有詳細的step-by-step的流程..net
而後用java寫了一個版本,尚未剪枝就ac啦.code
class Solution { int count = 0; List<Integer> finalRes; public String getPermutation(int n, int k) { int[] nums = new int[n]; for (int i = 0; i < n; i++) { nums[i] = i + 1; } //第幾個解. List<Integer> resTemp = new ArrayList<>(); boolean[] haveSeen = new boolean[n]; backtrack(nums, k, resTemp, haveSeen); StringBuilder res = new StringBuilder(); for (Integer i : finalRes) { res.append(i); } return res.toString(); } public void backtrack(int[] nums, int k, List<Integer> tempIndex, boolean[] haveSeen) { if (tempIndex.size() == nums.length) { count++; } if (count == k && tempIndex.size() == nums.length) { finalRes = new ArrayList<>(tempIndex); return; } else if (count < k && tempIndex.size() == nums.length) { tempIndex = new ArrayList<>(); } for (int i = 0; i < nums.length; i++) { if (haveSeen[i]) { continue; } tempIndex.add(nums[i]); haveSeen[i] = true; backtrack(nums, k, tempIndex, haveSeen); haveSeen[i] = false; tempIndex.remove(tempIndex.size() - 1); } } }
因爲前幾天後臺有同窗反饋,但願給出java版本的題解。因此又動手寫了一個python版本.ci
class Solution: def getPermutation(self, n, k): """ :type n: int :type k: int :rtype: str """ global count global finalRes count = 0 finalRes = [] def backtrack(nums, k, resTemp, haveSeen): global count global finalRes if count > k: return if len(resTemp) == len(nums): count += 1 if count == k and len(resTemp) == len(nums): finalRes = [str(_) for _ in resTemp] return elif count < k and len(resTemp) == len(nums): resTemp = [] for i in range(0, len(nums)): if count > k: break if haveSeen[i]: continue resTemp.append(nums[i]) haveSeen[i] = True backtrack(nums, k, resTemp, haveSeen) haveSeen[i] = False resTemp.pop() backtrack([_ + 1 for _ in range(0, n)], k, [], [False for _ in range(0, n)]) return "".join(finalRes)
後來這個版本提交的時候我覺得能夠洗洗睡啦.
結果,臥槽,竟然換一種語言就超時啦~~rem
這卻是個意外.難道個人python寫的有性能問題,不該該啊,不是:
人生苦短,我用python
我就繼續想剪枝,還能怎麼剪枝?
剪枝是啥,不就是跳過某些步驟嗎?
那哪些步驟能夠跳過呢.
4的全排列是:
1 + {2,3,4}全排列
2 + {1,3,4}全排列
3 + {1,2,4}全排列
4 + {1,2,3}全排列
彷佛能夠轉化成子問題啊.
因爲題目只要求出第幾個,咱們再看看個數的規律
1 + {2,3,4}全排列(3!個)
2 + {1,3,4}全排列(3!個)
3 + {1,2,4}全排列(3!個)
4 + {1,2,3}全排列(3!個)
這就很好了呀~
具體來講是:
數學之美啊,有木有。
而後就快速實現了python的code AC了.
class Solution: def getPermutation(self, n, k): nums = [str(_ + 1) for _ in range(0, n)] if k == 1: return "".join(nums) fact = 1 for i in range(2, n): fact *= i round = n - 1 k -= 1 finalRes = [] while round >= 0: index = int(k / fact) k %= fact finalRes.append(nums[index]) nums.remove(nums[index]) if round > 0: fact /= round round -= 1 return "".join(finalRes)
pulicity (n.) 曝光度,知名度
Publicize (v.) 宣傳
mass (n.)羣衆 (v.)彙集 (a.集中的)
civilian (a.)平民