-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrandom_pick_with_weight.py
99 lines (78 loc) · 1.91 KB
/
random_pick_with_weight.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#
# https://leetcode.com/problems/random-pick-with-weight/
#
import random
class Solution(object):
def __init__(self, w):
"""
:type w: List[int]
"""
self.len = len(w)
self.mapping = {}
self.max = 0
self.min = 10**5
for idx, entry in enumerate(w):
self.max += entry
self.min = min(self.min, entry)
self.mapping[self.max] = idx
self.intervals = sorted(self.mapping.keys())
def bin_search(self, some_val):
l, r = 0, self.len-1
if some_val <= self.intervals[l]:
return l
if some_val == self.intervals[r]:
return r
while l < r:
if r - 1 == l:
if self.intervals[l] > some_val:
return l
return r
m = l + (r-l) // 2
if self.intervals[m] > some_val:
r = m
elif self.intervals[m] < some_val:
l = m
else: # self.intervals[m] == some_val
return m
def pickIndex(self):
"""
:rtype: int
"""
cur_val = random.randint(1, self.max)
interval_idx = self.bin_search(cur_val)
return self.mapping[self.intervals[interval_idx]]
w = [5]
s = Solution(w)
cnt = {}
for _ in xrange(1000):
ii = s.pickIndex()
cnt[ii] = cnt.get(ii, 0) + 1
print cnt
w = [5, 1, 9, 4, 1]
s = Solution(w)
cnt = {}
for _ in xrange(1000):
ii = s.pickIndex()
cnt[ii] = cnt.get(ii, 0) + 1
print cnt
w = [1, 1, 1, 1, 1, 1]
s = Solution(w)
cnt = {}
for _ in xrange(1000):
ii = s.pickIndex()
cnt[ii] = cnt.get(ii, 0) + 1
print cnt
w = [4, 2]
s = Solution(w)
cnt = {}
for _ in xrange(1000):
ii = s.pickIndex()
cnt[ii] = cnt.get(ii, 0) + 1
print cnt
w = [1, 1, 10]
s = Solution(w)
cnt = {}
for _ in xrange(1000):
ii = s.pickIndex()
cnt[ii] = cnt.get(ii, 0) + 1
print cnt