我正在处理下面的问题和发布的代码我正在调试和问题陈述。实际上我试图找到一些参考解决方案,所有都是相似的,没有太多的解释。如果有人可以帮助解释逻辑如何工作,那将是伟大的。我特别感到困惑的是" for(i = 0,k - ; i
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.
代码参考,
#include <iostream>
using namespace std;
string getPermutation(int n, int k) {
int i,j,f=1;
// left part of s is partially formed permutation, right part is the leftover chars.
string s(n,'0');
for(i=1;i<=n;i++){
f*=i;
s[i-1]+=i; // make s become 1234...n
}
for(i=0,k--;i<n;i++){
f/=n-i;
j=i+k/f; // calculate index of char to put at s[i]
char c=s[j];
// remove c by shifting to cover up (adjust the right part).
for(;j>i;j--)
s[j]=s[j-1];
k%=f;
s[i]=c;
}
return s;
}
int main(int argc, const char * argv[])
{
// insert code here...
std::cout << getPermutation(4, 5) << endl;
return 0;
}
发布另一个更清晰的实现,
def kthperm(S, k): # nonrecursive version
P = []
while S != []:
f = factorial(len(S)-1)
i = int(floor(k/f))
x = S[i]
k = k%f
P.append(x)
S = S[:i] + S[i+1:]
return P
答案 0 :(得分:2)
问题陈述在排列的 lexical 排序中要求N个元素的Kth排列。
代码实现了一个非常好的算法,它按顺序直接生成Kth排列的元素,如下所示(伪代码):
GenerateKthPermutation(Set elements, int k)
{
if (elements.size()==1)
{
output(elements.getOnlyElement());
return;
}
int n = elements.size();
//there are n! permutations of elements
//no matter which one we choose as the _first_ element, there
//will be (n-1)! permutations of the remaining elements.
//The complete lexical ordering of permutations consists of:
//(n-1)! permutations that start with the smallest element, then
//(n-1)! permutations that start with the second smallest element, then
//(n-1)! permutations that start with the 3rd smallest element, etc.
//so the FIRST element in the (0-indexed) kth permutation, is the
//(0-indexed) floor(k/(n-1)!)th-largest element
int j = floor((k-1)/(n-1)!); //k-1, because the parameter is 1-indexed
//removeJthLargest(0) removes and returns the smallest element
//removeJthLargest(1) removes and returns the second-smallest
//etc.
output(elements.removeJthLargest(j));
//now output the correct permutation of remaining elements.
//we've skipped j*(n-1)! permutations, so subtract that from k
k -= j*(n-1)!;
//remember elements is 1 smaller now.
//in real life you would iterate here instead of recursing
GenerateKthPermutation(elements, k);
}
我希望能让事情变得清晰。要在评论中专门回答您的问题:
原始逻辑使用排序字符串来存储元素集。说&#34;通过移动来移除c的部分...&#34;是我说&#34; elements.removeJthLargest(j)&#34;的部分。它从字符串中删除了正确的元素,并将剩余的元素移动到一个新的,更小但仍然排序的字符串。