Permutation Sequence

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):

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

Given n and k, return the kth permutation sequence.

Note: Given n will be between 1 and 9 inclusive.


1.自己的方法,用迭代

#include <iostream>
#include <string>
using namespace std;
void swap(char& a, char& b){
    char c = a;
    a = b;
    b = c;
}

void getnext(string& s){
    int label = 0;
    for(int i = s.size()-1; i >= 0; i--){
        if(s[i]>s[i-1]){
            label = i-1;
            break;
        }
    }
    int min = label+1;
    for(int j = label+2; j < s.size(); j++){
        if(s[j] > s[label] && s[j] < s[min])
            min = j;
    }
    swap(s[min],s[label]);
    sort(s.begin()+label+1,s.end());
    return;
}
string getPermutation(int n, int k) {
    string s(n,'0');
    for(int i = 1; i <= n; i++){
        s[i-1]=i+'0';
    }
    if(n == 1 || k == 1)
        return s;
    while(--k > 0){
        getnext(s);
    }
    return s;
}

int main(int argc, const char * argv[]) {
    int n = 9;
    int k = 217778;
    string s = getPermutation( n, k);
    cout<<s<<endl;
    return 0;
}

但是在提交的时候,发现当n=9时,会超时;因此这里有第二个做法。

2.根据规律来找

比如:“123”,

可以看到第一位的开头数字,是可以计算出来的,即k/(n-1)!. 而第二位也可以用k/(n-2)!得到,这里的k=k%(n-1)!.以此类推

然后用一个数组存1~n,若某位数被取走,则用后面往前面移动一位的方式填补。

class Solution {
public:
string getPermutation(int n, int k) {
    string s(n,'0');
    string f(n,'0');
    for(int i = 1; i <= n; i++){
        f[i-1]=i+'0';
        s[i-1]=i+'0';
    }
    if(n == 1 || k == 1)
        return s;
    vector<int> vec(n);
    vec[0]=1;
    for(int p = 1; p < n; p++)
        vec[p] = vec[p-1]*p;
    int m = n-1;
    int alpha = 0;
    while(n-- > 0){
    if(k % vec[n] != 0){
        alpha = k/vec[n];
        k = k%vec[n];
    }else{
        alpha = k/vec[n]-1;
        k = k%vec[n]+vec[n];
    }
    s[m-n] = f[alpha];
    for(int q = alpha; q < f.size()-1; q++)
        f[q] = f[q+1];
    }
    return s;
}
};

3.别人的动态规划的代码

    vector<vector<int> > path(m);
    int ix = 0;
    int jx = 0;

    for(ix = 0; ix < m; ix++) {
        path[ix].resize(n);
    }

    path[m-1][n-1] = grid[m-1][n-1];

    if(m >= 1)
    for(ix = m-1, jx = n-2; jx >= 0; jx--) {
        path[ix][jx] = path[ix][jx+1] + grid[ix][jx];
    }

    if(n >= 1) 
    for(ix= m-2, jx=n-1; ix>=0; ix--) {
        path[ix][jx] = path[ix+1][jx] + grid[ix][jx];
    }

    if(m > 1 && n > 1) {


      for(ix = m-2; ix >= 0; ix--) {
        for(jx = n-2; jx >= 0; jx--) {

            path[ix][jx] = grid[ix][jx] + min(path[ix+1][jx], path[ix][jx+1]);
        }
      }
    }


    return path[0][0];
}


你可能感兴趣的:(LeetCode,C++,backtracking)