Random Pick with Blacklist - Problem
Random Pick with Blacklist
You're building a lottery system that needs to randomly select winners from a pool of participants, but some participants are disqualified (blacklisted). Your task is to design an efficient algorithm that can randomly pick a valid participant.
Given an integer
1. Initialize your system with the total count and blacklist
2. Pick random participants efficiently, ensuring each valid participant has an equal chance
The key challenge is to minimize random function calls while maintaining perfect randomness. Each call to
Example:
If
You're building a lottery system that needs to randomly select winners from a pool of participants, but some participants are disqualified (blacklisted). Your task is to design an efficient algorithm that can randomly pick a valid participant.
Given an integer
n representing the total number of participants (numbered from 0 to n-1) and an array blacklist containing the IDs of disqualified participants, you need to:1. Initialize your system with the total count and blacklist
2. Pick random participants efficiently, ensuring each valid participant has an equal chance
The key challenge is to minimize random function calls while maintaining perfect randomness. Each call to
pick() should return a random integer in [0, n-1] that's not blacklisted.Example:
If
n = 7 and blacklist = [2, 3, 5], valid participants are [0, 1, 4, 6]. Each should have a 25% chance of being selected. Input & Output
example_1.py โ Basic Usage
$
Input:
n = 7, blacklist = [2, 3, 5]
Operations: ["Solution", "pick", "pick", "pick", "pick"]
โบ
Output:
Valid returns: any of [0, 1, 4, 6] for each pick
๐ก Note:
With n=7, we have indices [0,1,2,3,4,5,6]. Removing blacklisted [2,3,5] leaves [0,1,4,6]. Each pick() should return one of these 4 values with equal probability (25% each).
example_2.py โ Edge Case Small
$
Input:
n = 4, blacklist = [1, 3]
Operations: ["Solution", "pick", "pick"]
โบ
Output:
Valid returns: any of [0, 2] for each pick
๐ก Note:
Only 2 valid numbers remain out of 4. The virtual array maps: original [0,1,2,3] with blacklist [1,3] becomes effective range [0,2) where index 1 is mapped to value 2.
example_3.py โ Heavy Blacklist
$
Input:
n = 10, blacklist = [0, 1, 2, 3, 4, 5, 6]
Operations: ["Solution", "pick", "pick", "pick"]
โบ
Output:
Valid returns: any of [7, 8, 9] for each pick
๐ก Note:
Most numbers are blacklisted, leaving only [7,8,9]. The algorithm efficiently maps the small valid range [0,3) to these tail values, avoiding expensive rejection sampling.
Visualization
Tap to expand
Understanding the Visualization
1
Count Valid Tickets
Calculate how many valid tickets exist: validCount = n - blacklist.length
2
Identify Problem Tickets
Find blacklisted tickets in positions [0, validCount) - these block our random draw
3
Create Substitutions
Map each problematic ticket to a valid ticket from positions [validCount, n)
4
Draw and Substitute
Generate random in [0, validCount), apply substitution if needed
Key Takeaway
๐ฏ Key Insight: Instead of rejection sampling (which wastes random calls), create a virtual mapping that transforms any random number in [0, validCount) into a valid result. This guarantees O(1) performance and perfect uniform distribution!
Time & Space Complexity
Time Complexity
O(b) initialization, O(1) per pick
Preprocessing takes O(blacklist_size), each pick is constant time with one random call
โ Linear Growth
Space Complexity
O(b)
Store mapping for blacklisted numbers that fall in [0, validCount) range
โ Linear Space
Constraints
- 1 โค n โค 109
- 0 โค blacklist.length โค min(105, n - 1)
- 0 โค blacklist[i] < n
-
All values in
blacklistare unique -
At most 2 ร 104 calls will be made to
pick
๐ก
Explanation
AI Ready
๐ก Suggestion
Tab
to accept
Esc
to dismiss
// Output will appear here after running code