置换的增长顺序

时间:2012-08-28 18:33:18

标签: algorithm big-o permutation

这是一个简单的程序,可以找到给定字符串的所有排列:

void perm( char str[], int len )
{
if ( len == 1 )
   cout << str << endl ;
else
    for ( int i=0; i<len; i++ ) {
        swap( str[len-1], str[i] ) ;
        perm( str, len-1 ) ;
        swap( str[len-1], str[i] ) ;
    }
}

此功能的T(n)是多少?如何计算这个函数的Big Oh(或Theta)?

3 个答案:

答案 0 :(得分:2)

for循环执行n递归,到n * T(n-1),再加上O(n),因为你还需要交换2n次,所以

T(n) = n*T(n-1)+O(n)

n = 5 for sake of my keyboard

T(n) = n*T(n-1) + n  
T(n) = n*[(n-1)*T(n-2) + (n-1)] + n  
T(n) = n*[(n-1)*[(n-2)*T(n-3) + (n-2)] + (n+1)] + n  
T(n) = n*[(n-1)*[(n-2)*[(n-3)*T(n-4) + (n-3)] + (n-2)] + (n-1)] + n  
T(n-4) = 1 ----------------------^  
Simplify 
T(n) = n*[(n-1)*[(n-2)*[(n-3) + (n-3)] + (n-2)] + (n-1)] + n  
T(n) = n*[(n-1)*[(n-2)*[2(n-3)] + (n-2)] + (n-1)] + n  
T(n) = n(n-1)(n-2)*(n-3)*2 + (n-1)(n-2) + n(n-1) + n  
T(n) = n! + O(n*n!)    <--  wrong, see comment for right answer
T(n) = O(n*n!)    <--  wrong, see comment for right answer

你看到了模式

答案 1 :(得分:2)

让初始输入字符串的长度为N.

让perm(str(size = N),len = i)调用的时间为T(i)

T(1) = N

T(i > 1) = iT(i-1) + i

然后所用的总时间是T(N),

要计算此重复的封闭形式,请参见此处:

https://math.stackexchange.com/questions/188119/closed-form-for-t1-k-tx-xtx-1-x

答案是:

T(N) is approximately (N + e - 1)N!

因此当N接近无穷大时,函数的性能是:

O((N + e - 1)N!) = O(N(N!))

答案 2 :(得分:1)

N项的可能排列数是N! (阶乘),这个代码似乎使用它输出的每个排列的O(1)运算。因此,构造成本为O(N!),相当于O(N ^ N)。

或者也许是O(N!* N),因为对于每个排列,N个项目都打印到控制台。