Fundamentals 8 min read

Efficient Random Index Selection for Duplicates – LeetCode 398 Explained

This article explains LeetCode problem 398—Random Pick Index—detailing two solutions: a hash‑map preprocessing method for fixed arrays and a reservoir‑sampling approach for streaming data, complete with Java, C++, and Python implementations and complexity analysis.

IT Services Circle
IT Services Circle
IT Services Circle
Efficient Random Index Selection for Duplicates – LeetCode 398 Explained

Problem Description

Platform: LeetCode Problem #: 398

Given an integer array that may contain duplicates, implement a function that returns a random index of a given target number. The target is guaranteed to exist in the array. The array can be very large, so solutions using excessive extra space will not pass.

Hash Table + Preprocessing (Fixed‑length data stream)

During construction, iterate over nums and store for each value a list of its indices in a hash map.

When pick(target) is called, retrieve the list of indices for target and return a random element.

Java implementation:

class Solution {
    Random random = new Random();
    Map<Integer, List<Integer>> map = new HashMap<>();
    public Solution(int[] nums) {
        int n = nums.length;
        for (int i = 0; i < n; i++) {
            List<Integer> list = map.getOrDefault(nums[i], new ArrayList<>());
            list.add(i);
            map.put(nums[i], list);
        }
    }
    public int pick(int target) {
        List<Integer> list = map.get(target);
        return list.get(random.nextInt(list.size()));
    }
}

C++ implementation:

class Solution {
public:
    unordered_map<int, vector<int>> map;
    Solution(vector<int>& nums) {
        int n = nums.size();
        for (int i = 0; i < n; i++) {
            map[nums[i]].push_back(i);
        }
    }
    int pick(int target) {
        vector<int>& list = map[target];
        return list[rand() % list.size()];
    }
};

Python implementation:

class Solution:
    def __init__(self, nums: List[int]):
        self.mapping = {}
        n = len(nums)
        for i in range(n):
            if nums[i] not in self.mapping:
                self.mapping[nums[i]] = []
            self.mapping[nums[i]].append(i)

    def pick(self, target: int) -> int:
        return random.choice(self.mapping.get(target, []))

Time complexity: O(n) for initialization, O(1) for each pick. Space complexity: O(n).

Reservoir Sampling (Variable‑length data stream) – TLE

If the array is not fully known in advance and arrives as a stream, preprocessing is infeasible. Reservoir sampling can select a random index with O(1) extra space.

During each pick, iterate over the stream, maintaining a count of matching indices and replace the current answer with probability 1/count.

Java implementation:

class Solution {
    Random random = new Random();
    int[] nums;
    public Solution(int[] _nums) {
        nums = _nums;
    }
    public int pick(int target) {
        int n = nums.length, ans = 0, cnt = 0;
        for (int i = 0; i < n; i++) {
            if (nums[i] == target) {
                cnt++;
                if (random.nextInt(cnt) == 0) ans = i;
            }
        }
        return ans;
    }
}

C++ implementation:

class Solution {
public:
    vector<int> nums;
    mt19937 random;
    Solution(vector<int>& _nums) : nums(_nums) {
        srand(time(nullptr));
        random.seed(rand());
    }
    int pick(int target) {
        int ans = -1, cnt = 0;
        for (size_t i = 0; i < nums.size(); i++) {
            if (nums[i] == target) {
                cnt++;
                if (uniform_int_distribution<>(0, cnt - 1)(random) == 0) {
                    ans = i;
                }
            }
        }
        return ans;
    }
};

Python implementation:

class Solution:
    def __init__(self, nums: List[int]):
        self.nums = nums
    def pick(self, target: int) -> int:
        ans, cnt = 0, 0
        for i in range(len(self.nums)):
            if self.nums[i] == target:
                cnt += 1
                if random.randint(0, cnt - 1) == 0:
                    ans = i
        return ans

Time complexity: O(n) per pick. Space complexity: O(1).

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

algorithmhash tablereservoir-samplingleetcode-398random-pick-index
IT Services Circle
Written by

IT Services Circle

Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.