您的位置:首页 > 产品设计 > UI/UE

Permutation Sequence

2016-04-29 11:09 423 查看
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):
"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.

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
!= 0){
alpha = k/vec
;
k = k%vec
;
}else{
alpha = k/vec
-1;
k = k%vec
+vec
;
}
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]);
}

4000
}
}

return path[0][0];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ leetcode backtracking