1. 程式人生 > >初次寫部落格,一堆爛程式碼奉上

初次寫部落格,一堆爛程式碼奉上

*原題:https://leetcode-cn.com/problems/permutation-sequence/description/
給出集合 [1,2,3,…,n],其所有元素共有 n! 種排列。
按大小順序列出所有排列情況,並一一標記,當 n = 3 時, 所有排列如下:
“123”
“132”
“213”
“231”
“312”
“321”
給定 n 和 k,返回第 k 個排列。
說明:
給定 n 的範圍是 [1, 9]。
給定 k 的範圍是[1, n!]。
示例 1:
輸入: n = 3, k = 3
輸出: “213”
示例 2:
輸入: n = 4, k = 9
輸出: “2314”*

拿到這題最容易讓人想到的方法就是:
1.先求出所有的全排列(方法自寫);
2.再將這些全排列轉化為int;
3.排序找到第k大元素(或者改寫快速排序找第k大元素,但是並沒有什麼本質上的改變);

但是很無奈,當n為9的時候 排序的時間是巨大的,而且給這些全排列儲存起來花費的空間也非常巨大。。。顯然是一種很差的方法。

通過分析 1—–>n的全排列我們可以發現:
1.第一個數字是從1—–>n排下去的(nums【】裡的元素依次排下去的);
2. 以第一個數字劃分為組(zu)的話 一共有 (n-1)!個;
3. 需要找的第k個全排列 變成了 相對於除去第一個數字而言的第k-(zu - 1)*zu_size個;

典型的遞迴演算法!!!
**舉個簡單的例子 n=4 ,k=15
1.以 1、2、3、4開頭的 共4組 每組6個((4-1)!)全排列
第k=15個在第 3組(首數字3),同時可以鎖定當前元素3為要加入str元素,
2.加入後 nums={1,2,4} k=(15-12)=3; 以1,2,4開頭的 又分為3組 每組2個((3-1)!)全排列第3個元素在第2組首數字為 2……….**
以下是爛程式碼:

class Solution {
public:
int jc(int n){
        if (n <= 1) return n;
        else return
n*jc(n - 1); } vector<int> jc_vector_table(){ vector<int>m; m.push_back(0); for (int i = 1; i <= 9; i++) m.push_back(jc(i)); return m; } string digui_qiu(vector<int> &nums, vector<int> &total, int k){ string str; if (k <= 1){ for (int i = 1; i <= nums.size() - 1; i++) str += to_string(nums[i]); return str; } int n = nums.size() - 1; int zu_size = total[n - 1]; int zu = k / zu_size; if (k%zu_size != 0) zu++; string tmp = to_string(nums[zu]); str += tmp; vector<int>::iterator p = nums.begin() + zu; nums.erase(p); k = k-(zu - 1)*zu_size; str+=digui_qiu(nums, total, k); return str; } string getPermutation(int n, int k) { string str; vector<vector<int>> m; vector<int> nums; vector<int> total; for (int i = 0; i <= n; i++) nums.push_back(i); total=jc_vector_table(); str = digui_qiu(nums, total, k); cout << str << endl; return str; } };