Create a random permutation of 1..N in constant space
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Creating a random permutation of a sequence from 1 to N in constant space is a fascinating problem. It provides a deep dive into algorithmic efficiency and understanding of data structures. This article will explore this concept, offering technical insights and examples to clarify the approach.
Understanding the Problem
The task of generating a random permutation of numbers from 1 to N requires us to arrange these numbers in a random order. While it's straightforward to achieve with additional storage (i.e., using O(N) space), generating the permutation "in-place" using only a constant amount of extra space adds an exciting challenge to the problem.
Key Concepts
- Permutation: A rearrangement of elements in a particular order.
- In-place: An algorithm where the output occupies the same location as the input, minimizing extra space usage.
- Randomness: Ensuring each permutation of elements has an equal probability of occurrence.
To maintain these properties, we utilize the Fisher-Yates shuffle (also known as the Knuth shuffle), which is straightforward and efficient in producing a uniformly random permutation.
Fisher-Yates Shuffle Algorithm
Steps to Implement Fisher-Yates Shuffle
The Fisher-Yates shuffle works by iterating through the array and swapping each element with a randomly chosen element that comes after it (including itself). This operation ensures each element has an equal probability of ending up in any position.
- Initialize: Given an array `A` of size `N` with elements 1 to N.
- Iteration:
- For each index `i` from 0 to `N-1`, do the following:
- Generate a random index `j` from `i` to `N-1`.
- Swap elements `A[i]` and `A[j]`.
Example
Consider an array `A` with elements `[1, 2, 3, 4]`.
- Iteration 1: `i = 0`
- Choose a random index `j` between `0` and `3`. Assume `j = 2`.
- Swap `A[0]` with `A[2]`, resulting in `[3, 2, 1, 4]`.
- Iteration 2: `i = 1`
- Choose `j` between `1` and `3`. Assume `j = 1`.
- Swap `A[1]` with `A[1]` (no change), resulting in `[3, 2, 1, 4]`.
- Iteration 3: `i = 2`
- Choose `j` between `2` and `3`. Assume `j = 3`.
- Swap `A[2]` with `A[3]`, resulting in `[3, 2, 4, 1]`.
In these steps, each element of the array has been shuffled randomly. The process guarantees a statistically uniform distribution, essential for random permutations.
Space Complexity Analysis
The Fisher-Yates algorithm yields an advantage in terms of space efficiency. It operates with an O(1) space complexity because it produces permutations in-place without requiring extra storage for indices or auxiliary arrays. The only additional space consumed is for a few variables used during swapping and iteration.
Edge Cases
- Single Element: When N = 1, the only permutation is `[1]` itself.
- Large N: Ensure that the random number generation is efficient and can handle the range up to N-1 without bias.
Conclusion
The Fisher-Yates shuffle is a powerful tool for producing random permutations in scenarios where space is a constraint. Through its simple yet profound operation of swapping elements in-place, it provides a compelling solution to the problem.
Summary Table
| Aspect | Description |
| Algorithm | Fisher-Yates (Knuth) shuffle |
| Complexity | Time: O(N), Space: O(1) |
| Uniformity | Ensures uniform distribution of permutations |
| Operations | Swaps each element with an element following it |
| Edge Cases | Handles N = 1, large N efficiently |
By understanding and implementing this algorithm, you can efficiently tackle problems requiring permutations in limited space settings with confidence.

