398. Random Pick Index
Given an integer array nums with possible duplicates, randomly output the index of a given target number. You can assume that the given target number must exist in the array.
Implement the Solution class:
- Solution(int[] nums) Initializes the object with the array nums.
- int pick(int target) Picks a random index i from nums where nums[i] == target. If there are multiple valid i’s, then each index should have an equal probability of returning.
Example 1:
Input:
[“Solution”, “pick”, “pick”, “pick”]
[[[1, 2, 3, 3, 3]], [3], [1], [3]]
Output:
[null, 4, 0, 2]
Explanation:
Solution solution = new Solution([1, 2, 3, 3, 3]);
solution.pick(3); // It should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning.
solution.pick(1); // It should return 0. Since in the array only nums[0] is equal to 1.
solution.pick(3); // It should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning.
Constraints:
- 1 < = n u m s . l e n g t h < = 2 ∗ 1 0 4 1 <= nums.length <= 2 * 10^4 1<=nums.length<=2∗104
- − 2 31 < = n u m s [ i ] < = 2 31 − 1 -2^{31} <= nums[i] <= 2^{31} - 1 −231<=nums[i]<=231−1
- target is an integer from nums.
- At most 1 0 4 10^4 104 calls will be made to pick.
From: LeetCode
Link: 398. Random Pick Index
Solution:
Ideas:
1. Struct Definition:
- Solution struct holds:
- nums: a pointer to the input array.
- numsSize: the size of the array.
2. solutionCreate:
- This function initializes the Solution object with the given nums array and stores its size in numsSize.
3. solutionPick:
- We use reservoir sampling to randomly select an index of target:
- We iterate through the nums array.
- For each occurrence of target, we increment the count of valid indices.
- Using the formula rand() % count == 0, we decide whether to select the current index as the result. This ensures that each index has an equal probability of being selected.
4. solutionFree:
- This function frees the dynamically allocated memory for the Solution object.
Code:
typedef struct {
int* nums; // Array to store the nums
int numsSize; // Size of the array
} Solution;
Solution* solutionCreate(int* nums, int numsSize) {
Solution* obj = (Solution*)malloc(sizeof(Solution));
obj->nums = nums;
obj->numsSize = numsSize;
return obj;
}
int solutionPick(Solution* obj, int target) {
int count = 0; // To count the number of occurrences of target
int result = -1; // Store the result index
// Iterate over the nums array
for (int i = 0; i < obj->numsSize; i++) {
if (obj->nums[i] == target) {
count++;
// Reservoir sampling: replace result with probability 1/count
if (rand() % count == 0) {
result = i;
}
}
}
return result;
}
void solutionFree(Solution* obj) {
// No need to free the nums array because it is passed in externally
free(obj);
}
/**
* Your Solution struct will be instantiated and called as such:
* Solution* obj = solutionCreate(nums, numsSize);
* int param_1 = solutionPick(obj, target);
* solutionFree(obj);
*/