329. Random Pick Index
Design a class over an integer array nums that may contain duplicates:
Solution(nums)— receives the array once and builds whatever structure you need.pick(target)— returns an indexisuch thatnums[i] == target. Every queriedtargetis guaranteed to exist innums.
In the interview version of this problem, pick must return a uniformly random index among all positions holding target (reservoir sampling is the famous answer — the editorial covers it). Because this judge compares output exactly, we pin a deterministic rule instead: repeated calls with the same target cycle through its occurrence indices in increasing order — the first call returns the smallest such index, the second the next-smallest, and after the largest it wraps back around to the smallest. Each distinct target keeps its own independent cycle.
Example 1:
Input: nums = [1, 2, 3, 3, 3], picks = [3, 1, 3, 3, 3]
Output: [2, 0, 3, 4, 2]
Explanation: The value 3 lives at indices 2, 3 and 4. Successive picks of 3 walk that list in order and wrap: 2, then 3, then 4, then back to 2. The single pick of 1 returns its only index, 0.
Example 2:
Input: nums = [7, 7, 7], picks = [7, 7, 7, 7]
Output: [0, 1, 2, 0]
Explanation: Every element equals 7, so picks cycle through indices 0, 1, 2 and then wrap to 0 on the fourth call.
Constraints:
- 1 ≤ nums.length ≤ 2 * 10⁴
- -2³¹ ≤ nums[i] ≤ 2³¹ - 1
- Every target passed to pick occurs at least once in nums.
- At most 10⁴ calls will be made to pick.
Hints:
Where does each value live? One pass over nums can build a hash map from value to the list of its indices (already in increasing order, since you append as you scan).
Keep a second map counting how many times each target has been picked so far; the c-th call (0-based) for a target with m occurrences returns occurrences[c % m]. For the true random variant, read up on reservoir sampling: scan the occurrences and replace your current choice of the c-th match with probability 1/c.
▶ Run checks these sample cases. Submit also runs hidden edge cases.
Input: nums = [1, 2, 3, 3, 3], picks = [3, 1, 3, 3, 3]
Expected output: [2, 0, 3, 4, 2]