Given n and k, return the kth permutation sequence
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The naive way to find the kth permutation is to generate every permutation, sort them, and pick one. That works for tiny inputs, but it becomes impractical very quickly because the number of permutations grows as n!.
The Key Idea: Factorial Blocks
List the numbers from 1 to n in lexicographic order. For a fixed first digit, the remaining n - 1 digits can be arranged in (n - 1)! ways. That means permutations are naturally grouped into blocks of equal size.
For n = 4, each leading digit owns 3! = 6 permutations:
- '
1xxxcovers permutations1through6' - '
2xxxcovers permutations7through12' - '
3xxxcovers permutations13through18' - '
4xxxcovers permutations19through24'
So if k = 9, the answer is in the block starting with 2 because 9 falls in the second group of six.
Converting k Into Choices
The standard trick is to convert k from one-based indexing to zero-based indexing first. That makes division cleaner.
Suppose n = 4 and k = 9.
- Start with available digits:
[1, 2, 3, 4] - Convert
kto zero-based:k = 8 - Compute
3! = 6 - Choose index
8 // 6 = 1, so the first digit is2 - Remove
2, leaving[1, 3, 4] - Update
k = 8 % 6 = 2 - Compute
2! = 2 - Choose index
2 // 2 = 1, so the next digit is3 - Remove
3, leaving[1, 4] - Update
k = 2 % 2 = 0 - Compute
1! = 1 - Choose index
0 // 1 = 0, so the next digit is1 - The remaining digit is
4
The result is 2314.
Python Implementation
Here is a complete implementation that runs in O(n^2) time because removing from the middle of a list costs linear time. For interview-sized inputs, that is usually fine.
Output:
Why This Works
At every step, permutations are partitioned into equal blocks. The block size depends only on how many positions remain. Integer division tells you which block contains the desired answer, and modulo tells you where to continue searching inside that block.
This is sometimes called the factorial number system because the position is described using factorial-sized units rather than powers of ten.
Handling Invalid Input
The valid range for k is from 1 to n!. If k falls outside that range, there is no such permutation.
This check prevents silent failures or index errors.
Complexity Discussion
Generating all permutations takes O(n! * n) time and a large amount of memory if you store them. The factorial-block method avoids that explosion. You only build the answer one digit at a time.
The implementation above uses a list for the remaining digits, so each pop(index) may shift elements. That gives O(n^2) time overall. More advanced data structures can reduce selection cost, but for the common interview version of the problem, the list-based solution is both correct and easy to explain.
Common Pitfalls
The most common bug is forgetting that the problem statement usually counts permutations starting at 1, while Python lists are zero-based. If you do not subtract 1 from k at the start, every block calculation is off.
Another mistake is using n! at every step instead of (remaining - 1)!. The block size should depend on the number of digits left after fixing the current position.
A third problem is not validating k. If k is larger than n!, eventually the selected index will be out of range.
Summary
- The
kth permutation can be found without generating every permutation. - Permutations are grouped into factorial-sized blocks.
- Convert
kto zero-based indexing before doing the math. - At each step, use division to choose a digit and modulo to update the remainder.
- A simple list-based implementation is usually the right balance of clarity and performance.

