Given a stream of numbers, select a random number from the stream such that each number has an equal probability of being chosen. You are allowed to use only O(1) space, and the input is in the form of a stream, so you cannot store previously seen numbers.
Input: Stream =[10,20,30,40]Output: 20(or 10 or 30 or 40, each with probability 1/4)Explanation: Each number in the stream is equally likely to be chosen.
The key idea is to maintain a single candidate answer as you process the stream. For each new number, you randomly decide whether to replace the current answer, ensuring that every number has an equal chance of being selected, regardless of the stream length.
#include<vector>classSolution {
public:int selectRandom(const std::vector<int>& arr) {
int ans =-1, i =0;
auto it = arr.begin();
while (it != arr.end()) {
++i;
if (rand() % i ==0) ans =*it;
++it;
}
return ans;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
funcSelectRandom(arr []int) int {
ch:= make(chanint)
gofunc() {
for_, v:=rangearr {
ch<-v }
close(ch)
}()
ans:=-1i:=0fornum:=rangech {
i++ifrand.Intn(i) ==0 {
ans = num }
}
returnans}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.Iterator;
import java.util.Arrays;
classSolution {
publicintselectRandom(int[] arr) {
Iterator<Integer> stream = Arrays.stream(arr).iterator();
int ans =-1, i = 0;
while (stream.hasNext()) {
int num = stream.next();
i++;
if (Math.random() < 1.0/ i) ans = num;
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
classSolution {
funselectRandom(arr: IntArray): Int {
val stream = arr.asSequence()
var ans = -1var i = 0for (num in stream) {
i++if (Math.random() < 1.0 / i) ans = num
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
classSolution:
defselect_random(self, arr: list[int]) -> int:
defstream():
for v in arr:
yield v
ans =Nonefor i, num in enumerate(stream(), 1):
if random.randint(1, i) ==1:
ans = num
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use rand::Rng;
impl Solution {
pubfnselect_random(arr: &[i32]) -> i32 {
letmut ans = None;
letmut i =0;
letmut stream = arr.iter();
whilelet Some(&num) = stream.next() {
i +=1;
if rand::thread_rng().gen_range(1..=i) ==1 {
ans = Some(num);
}
}
ans.unwrap()
}
}