Example #1
0
// naive version
// assumption: seq == {0, ..., n - 1} as set
bool johnson_trotter(std::vector<int>& seq)
{
    assert(seq.size() <= std::numeric_limits<int>::max());
    const int n = seq.size();
    std::vector<int> invseq(n, 0);

    for (int i = 0; i < n; ++i) {
        invseq[seq[i]] = i;
    }

    // step 1
    std::vector<int> y(n, 0);
    for (int i = 0; i < n; ++i) {
        int sign = sgn(invseq.begin(), invseq.begin() + i);
        y[i] = invseq[i] - sign;
    }

    // step 2
    int i = n - 1;
    while (i >= 0) {
        if ((0 <= y[i] && y[i] < n) && seq[y[i]] < i) {
            break;
        }
        i--;
    }

    // last permutation
    if (i < 0) {
        return false;
    }

    std::swap(seq[invseq[i]], seq[y[i]]);
    return true;
}
    string getPermutation(int n, int k) {
		vector<int> invseq(n,0);
		for( int i=1;i<k;++i){
			int j=n-1;
			while(j>=0 && invseq[j]==n-1-j)--j;
			if (j==-1)invseq=vector<int>(n,0);
			else{
				++invseq[j];
				while(++j<n)invseq[j]=0;
			}
		}
		string seq(n,0),perm(n,0);
		//cout<<vector2string<int>(invseq)<<endl;
		for (int i=0;i<n;++i)seq[i]='1'+i;
		for (int i=0;i<n;++i){
			perm[i]=seq[invseq[i]];
			seq.erase(invseq[i],1);
		}
		return perm;
    }