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.
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.
classSolution {
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);
}
};
classSolution {
publicint[]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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
classSolution {
funrandomSubset(arr: IntArray, m: Int): IntArray {
val n = arr.size
val res = arr.copyOf()
for (i in0 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)
}
}
1
2
3
4
5
6
7
8
9
10
11
from typing import List
import random
classSolution:
defrandom_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]
1
2
3
4
5
6
7
8
9
10
11
12
impl Solution {
pubfnrandom_subset(arr: &mut [i32], m: usize) -> Vec<i32> {
let n = arr.len();
letmut res = arr.to_vec();
letmut rng = rand::thread_rng();
for i in0..m {
let j = i + rng.gen_range(0..(n - i));
res.swap(i, j);
}
res[..m].to_vec()
}
}