在字典顺序中查找排列列表中给定排列的索引

时间:2011-05-07 15:03:31

标签: algorithm math permutation combinatorics

  

可能重复:
  Given a string and permutation of the string. Find the index of this permuted string in the sorted list of the permutations of the string.

这是一个面试问题。让按字典顺序列出排列。例如,123132213231312321。给定排列在这样的列表中找到它的索引。例如,排列213的索引是2(如果我们从0开始)。

平凡地说,我们可以使用next_permutation算法以字典顺序生成下一个排列,但它会导致O(N!)解,这显然是不可行的。有没有更好的解决方案?

4 个答案:

答案 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);   
}