这是一个面试问题。让按字典顺序列出排列。例如,123
,132
,213
,231
,312
,321
。给定排列在这样的列表中找到它的索引。例如,排列213
的索引是2(如果我们从0开始)。
平凡地说,我们可以使用next_permutation
算法以字典顺序生成下一个排列,但它会导致O(N!)解,这显然是不可行的。有没有更好的解决方案?
答案 0 :(得分:3)
我想到了这个解决方案(但我还没有测试过)。
第一个数字是从1到N的范围,因此您可以从第一个数字得出您的排列是否在哪个块大小(N-1)!
2*(2!) + X where X = 0..2!-1
然后你可以递归地将它应用于下一个数字(这是(N-1)!排列中的一个)。
因此,使用任意N,您可以执行以下算法:
X = 0
while string <> ""
X += ((first digit) - 1) * (N-1)!
decrease all digits in string by 1 which are > first digit
remove first digit from string
N -= 1
return X
在你的情况下:
X = 2
s = "213"
X += (2-1) * 2! => 2
s = "12"
X += (1-1) * 1! => 2
s = "1"
X += (1-1) * 0! => 2
因此该算法为O(N ^ 2)。
答案 1 :(得分:2)
将排列中的数字中的第一个数字的索引乘以(n-1)!
,并添加剩余排列的索引。
例如,2
的索引为1
,而13
的索引为0
,因此结果为1 * (3-1)! + 0 = 1 * 2 = 2
。
答案 2 :(得分:2)
N!
答案 3 :(得分:1)
在使用递归的C中,它将是这样的
int index(char *abc, int size) { if(abc ==0 || *abc==0 || size == 0) { return 0;; } return ((abc[0] - '0') * pow(2,size-1)) + index(abc + 1, size -1); }