问题:全排列按字典序排序,每个排列都对应有一个序号。1.根据序号求排列;2.根据排列求序号。
思想:n的阶乘的进制思想,从前往后一次是n!, (n-1)!, …, 2!, 1!。
代码:
1.根据排列求序号
//一个排列在字典序全排列中的序号,输入:一个排列,输出:排列的序号
int perm2num(vector<int> p){
int n=p.size();
int num=0;
for(int i=n-2,k=1;i>=0;i--){
for(int j=i+1;j<n;j++){
if(p[j]<p[i]){ //i后面有m个比它小的数,num+=m*k;
num+=k;
}
}
k*=n-i; //k=(n-i)!
}
return num+1;
}
2.根据序号求排列
//对应序号的排列,输入:排列的序号,输出:排列
vector<int> &num2perm(int n,int num){
static vector<int> ret;
vector<int> candidate(n,0);
int k=1,index;
for(int i=0;i<n;i++){
candidate[i]=i+1; //candidate={1,2,...,n}
k*=i+1; //k=n!
}
for(int i=0;i<n;i++){
k/=n-i;
index = (num-1)/k; //num-1 -> candidate[index]
num-=index*k; //num-=index*k;
ret.push_back(candidate[index]);
candidate.erase(candidate.begin()+index);
}
return ret;
}