If it doesn't matter to you which permutations which indexes will get, then the solution O (n) becomes possible, given that arithmetic operations with arbitrary integers are O (1).
For example, see the article “ Ranking and Unlocking Permutations in Linear Time ” by Wendy Mirwold and Frank Rusik.
In short, there are two ideas.
(1) Consider the Fisher-Yates shuffle method for generating random permutation (pseudo code below):
p = [0, 1, ..., n-1] for i := 0 upto n-1: j := random_integer (0, i) exchange p[i] and p[j]
This transformation is injective: if we give it another sequence of random integers, then it is guaranteed that it will perform another permutation. Thus, we replace random integers with nonrandom ones: the first is 0, the second is 0 or 1, ..., the last can be any integer from 0 to n-1.
(2) There are n! permutations of order n. Now we want to write an integer from 0 to n! -1 in the factorial system : the last digit is always 0, the previous one is 0 or 1, ..., and there are n possibilities from 0 to n-1 for the first digit. Thus, we get a unique sequence for filing the above pseudocode using.
Now, if we consider the division of our number by an integer from 1 to n by the operation O (1), the conversion of the number into the factorial system O (n) of such divisions. This, strictly speaking, is not true: for large n, the number n! contains the order of binary digits O (n log n), and the cost of separation is proportional to the number of digits.
In practice, for small n, O (n ^ 2) or O (n log n) methods to rank or cancel permutation, as well as methods that require storage of O (2 ^ n) or O (n!) For storage, some previously calculated values may be faster than the O (n) method, which includes integer division, which is a relatively slow operation on modern processors. For n large enough for n! does not fit into the machine word, "O (n) if the order-n! integer operations are an O (1) argument", stops working. Thus, you might be better off for small and large n if you do not insist that it is theoretically O (n).