LeetCode 398. Random Pick Index
原题链接在这里:https://leetcode.com/problems/random-pick-index/
题目:
Given an array of integers 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.
Note:
The array size can be very large. Solution that uses too much extra space will not pass the judge.
Example:
int[] nums = new int[] {1,2,3,3,3}; Solution solution = new Solution(nums); // pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning. solution.pick(3); // pick(1) should return 0. Since in the array only nums[0] is equal to 1. solution.pick(1);
题解:
The question asks no more space, thus try to get pick upon original nums array.
Use Reservoir Sampling: https://www.youtube.com/watch?v=A1iwzSew5QY
Basically, when iterating nums and encounter num == target, accumlate the count and get the random between [0, count).
If random == 0, then update the res index to current index.
Time Complexity: pick, O(n).
Space: O(1). No more array space, since it is pointing to given nums.
AC Java:
1 class Solution { 2 int [] nums; 3 Random rand; 4 5 public Solution(int[] nums) { 6 this.nums = nums; 7 rand = new Random(); 8 } 9 10 public int pick(int target) { 11 int res = -1; 12 int count = 0; 13 for(int i = 0; i<nums.length; i++){ 14 if(nums[i] != target){ 15 continue; 16 } 17 18 if(rand.nextInt(++count) == 0){ 19 res = i; 20 } 21 } 22 23 return res; 24 } 25 } 26 27 /** 28 * Your Solution object will be instantiated and called as such: 29 * Solution obj = new Solution(nums); 30 * int param_1 = obj.pick(target); 31 */
We could also use a HashMap to maintain the num and list of indices.
Get the list of indices based on target and return a random index.
Time Complexity: O(n). n = nums.length.
Space: O(n).
AC Java:
1 class Solution { 2 HashMap<Integer, List<Integer>> hm; 3 Random rand; 4 public Solution(int[] nums) { 5 rand = new Random(); 6 hm = new HashMap<>(); 7 for(int i = 0; i < nums.length; i++){ 8 hm.putIfAbsent(nums[i], new ArrayList<Integer>()); 9 hm.get(nums[i]).add(i); 10 } 11 } 12 13 public int pick(int target) { 14 List<Integer> ids = hm.get(target); 15 return ids.get(rand.nextInt(ids.size())); 16 } 17 } 18 19 /** 20 * Your Solution object will be instantiated and called as such: 21 * Solution obj = new Solution(nums); 22 * int param_1 = obj.pick(target); 23 */