The amortized complexity of std::next_permutation?

前端 未结 3 2023
暖寄归人
暖寄归人 2020-12-08 21:33

I just read this other question about the complexity of next_permutation and while I\'m satisfied with the response (O(n)), it seems like the algorithm might have a nice amo

3条回答
  •  粉色の甜心
    2020-12-08 22:02

    I am not really sure of the exact implementation of std::next_permutation, but if it is the same as Narayana Pandita's algorithm as desribed in the wiki here: http://en.wikipedia.org/wiki/Permutation#Systematic_generation_of_all_permutations,

    assuming the elements are distinct, looks like it is O(1) amortized! (Of course, there might be errors in the below)

    Let us count the total number of swaps done.

    We get the recurrence relation

    T(n+1) = (n+1)T(n) + Θ(n2)

    (n+1)T(n) comes from fixing the first element and doing the swaps for the remaining n.

    Θ(n2) comes from changing the first element. At the point we change the first element, we do Θ(n) swaps. Do that n times, you get Θ(n2).

    Now let X(n) = T(n)/n!

    Then we get

    X(n+1) = X(n) + Θ(n2)/(n+1)!

    i.e there is some constant C such that

    X(n+1) <= X(n) + Cn2/(n+1)!

    Writing down n such inequalities gives us

    X(n+1) - X(n) <= Cn2/(n+1)!

    X(n) - X(n-1) <= C(n-1)2/(n)!

    X(n-1) - X(n-2) <= C(n-2)2/(n-1)!

    ...

    X(2) - X(1) <= C12/(1+1)!

    Adding these up gives us X(n+1) - X(1) <= C(\sum j = 1 to n (j^2)/(j+1)!).

    Since the infinite series \sum j = 1 to infinity j^2/(j+1)! converges to C', say, we get X(n+1) - X(1) <= CC'

    Remember that X(n) counts the average number of swaps needed (T(n)/n!)

    Thus the average number of swaps is O(1).

    Since finding the elements to swap is linear with the number of swaps, it is O(1) amortized even if you take other operations into consideration.

提交回复
热议问题