Randomly generate m integers from an array of size n
HardUpdated: Sep 12, 2025
Problem
Given an array of size n, write a method to randomly select a set of m distinct elements from it, such that each subset of size m is equally likely to be chosen.
Examples
Example 1
Input: arr = [1, 2, 3, 4, 5], m = 3
Output: [2, 5, 1] (or any random subset of 3 elements)
Explanation: Each possible subset of 3 elements is equally likely.
Example 2
Input: arr = [10, 20, 30, 40], m = 2
Output: [30, 10] (or any random subset of 2 elements)
Explanation: Each possible subset of 2 elements is equally likely.
Solution
Method 1 – Fisher-Yates Shuffle (Partial Shuffle)
Intuition
To select m elements uniformly at random from an array of size n, we can use a partial Fisher-Yates shuffle. By shuffling only the first m positions, we guarantee that every subset of size m is equally likely.
Approach
- Make a copy of the input array to avoid modifying the original.
- For each position
ifrom0tom-1:- Pick a random index
jin the range[i, n-1]. - Swap the elements at positions
iandj.
- Pick a random index
- After
mswaps, the firstmelements of the array are a random subset. - Return the first
melements.
Code
C++
class Solution {
public:
std::vector<int> randomSubset(std::vector<int> arr, int m) {
int n = arr.size();
for (int i = 0; i < m; ++i) {
int j = i + rand() % (n - i);
std::swap(arr[i], arr[j]);
}
return std::vector<int>(arr.begin(), arr.begin() + m);
}
};
Go
func randomSubset(arr []int, m int) []int {
n := len(arr)
res := make([]int, n)
copy(res, arr)
for i := 0; i < m; i++ {
j := i + rand.Intn(n-i)
res[i], res[j] = res[j], res[i]
}
return res[:m]
}
Java
class Solution {
public int[] randomSubset(int[] arr, int m) {
int n = arr.length;
int[] res = arr.clone();
Random rand = new Random();
for (int i = 0; i < m; i++) {
int j = i + rand.nextInt(n - i);
int temp = res[i];
res[i] = res[j];
res[j] = temp;
}
return Arrays.copyOf(res, m);
}
}
Kotlin
class Solution {
fun randomSubset(arr: IntArray, m: Int): IntArray {
val n = arr.size
val res = arr.copyOf()
for (i in 0 until m) {
val j = i + (0 until (n - i)).random()
val tmp = res[i]
res[i] = res[j]
res[j] = tmp
}
return res.sliceArray(0 until m)
}
}
Python
from typing import List
import random
class Solution:
def random_subset(self, arr: List[int], m: int) -> List[int]:
n = len(arr)
res = arr[:]
for i in range(m):
j = random.randint(i, n - 1)
res[i], res[j] = res[j], res[i]
return res[:m]
Rust
impl Solution {
pub fn random_subset(arr: &mut [i32], m: usize) -> Vec<i32> {
let n = arr.len();
let mut res = arr.to_vec();
let mut rng = rand::thread_rng();
for i in 0..m {
let j = i + rng.gen_range(0..(n - i));
res.swap(i, j);
}
res[..m].to_vec()
}
}
TypeScript
class Solution {
randomSubset(arr: number[], m: number): number[] {
const n = arr.length;
const res = arr.slice();
for (let i = 0; i < m; i++) {
const j = i + Math.floor(Math.random() * (n - i));
[res[i], res[j]] = [res[j], res[i]];
}
return res.slice(0, m);
}
}
Complexity
- ⏰ Time complexity:
O(m)— We performmswaps, each in constant time. - 🧺 Space complexity:
O(n)— We copy the array to avoid modifying the original.