Find kth Permutation
Explore how to determine the kth permutation of a sequence of n elements by understanding the factorial concept and applying a recursive strategy to select elements in blocks. This lesson guides you to optimize the search for permutations beyond naive generation, helping you implement a linear time solution with clear mathematical reasoning.
Statement
Given two numbers and , find k permutation of . For , all permutations are (with ordering):
Sample input
Here 4 is the number and 8 is the k permutation to be calculated.
4, 8
Expected output
2143
We need to find the k permutation here.
Try it yourself
Solution
Let’s discuss a few basics first. We know that is the number of permutations for a set of size . Another obvious and important concept is that if we choose an element for the first position, then the total permutations of the remaining elements are .
For example, if we are given the elements {1, 2, 3, 4}, and we pick 1 as our first element, then for the remaining elements, we have the following permutations:
It is equal to which we found with . This number is the same even if we pick another element for the first slot.
Naive solution:
-
A naive way of finding the permutation will be to find all permutations and then return the permutation.
-
Another way to say this is to maintain a running count of permutations seen so far and return once the permutation is reached.
Optimized solution:
- We can do better, if we look closely at the diagram above. If we are given and we somehow guess which block it’s going to lie in, that will help us find at least the first element.
- Similarly, within that block, if we can identify a sub-block where resides, it will help us find the second element. We can do this recursively until we run out of options. Here is a visual representation of this approach if :
Here is the algorithm, we will follow:
If the input vector is empty return the result vector
block_size = (n-1)! ['n' is the size of vector]
Figure out which block k will lie in and select the first element of that block
(this can be done by doing (k-1)/block_size )
Append a selected element to the result vector and remove it from the original input vector
Deduce from k the blocks that are skipped, i.e, k = k - selected*block_size, and goto step 1
Let’s understand this example with step by step below:
Time complexity
The time complexity of this solution is linear, , because we use memoization to avoid re-calculation of factorial values.
Space complexity
The space complexity of this solution is linear, .