// 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; }