1+ """
2+ Given an array of integers with possible duplicates, randomly output the index of a given target number. You can assume
3+ that the given target number must exist in the array.
4+
5+ Note:
6+ The array size can be very large. Solution that uses too much extra space will not pass the judge.
7+
8+ Example:
9+
10+ int[] nums = new int[] {1,2,3,3,3};
11+ Solution solution = new Solution(nums);
12+
13+ // pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning.
14+ solution.pick(3);
15+
16+ // pick(1) should return 0. Since in the array only nums[0] is equal to 1.
17+ solution.pick(1);
18+ """
19+ import random
20+
21+ __author__ = 'Daniel'
22+
23+
24+ class Solution (object ):
25+ def __init__ (self , nums ):
26+ """
27+ :type nums: List[int]
28+ """
29+ self .A = nums
30+
31+ def pick (self , target ):
32+ """
33+ O(n)
34+ Reservoir Sampling
35+ :type target: int
36+ :rtype: int
37+ """
38+ sz = 0
39+ ret = None
40+ for idx , val in enumerate (self .A ):
41+ if val == target :
42+ sz += 1
43+ p = random .randrange (0 , sz )
44+ if p == 0 :
45+ ret = idx
46+
47+ return ret
48+
49+
50+ class SolutionError (object ):
51+ def __init__ (self , nums ):
52+ """
53+ Reservoir Sampling
54+ Assume pick is only called once
55+ :type nums: List[int]
56+ """
57+ self .d = {}
58+ for idx , val in enumerate (nums ):
59+ if val not in self .d :
60+ self .d [val ] = (idx , 1 )
61+ else :
62+ prev , sz = self .d [val ]
63+ p = random .randrange (0 , sz )
64+ if p < sz :
65+ self .d [val ] = (idx , sz + 1 )
66+ else :
67+ self .d [val ] = (prev , sz + 1 )
68+
69+ def pick (self , target ):
70+ """
71+ :type target: int
72+ :rtype: int
73+ """
74+ return self .d [target ][0 ]
0 commit comments