Skip to content

Commit 124f491

Browse files
committed
Create random-pick-with-blacklist.py
1 parent 62d5c5a commit 124f491

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

Python/random-pick-with-blacklist.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Time: ctor: O(nlogn)
2+
# pick: O(logn)
3+
# Space: O(n)
4+
5+
# Given a blacklist B containing unique integers from [0, N),
6+
# write a function to return a uniform random integer from
7+
# [0, N) which is NOT in B.
8+
#
9+
# Optimize it such that it minimizes the call to system’s Math.random().
10+
#
11+
# Note:
12+
#
13+
# 1 <= N <= 1000000000
14+
# 0 <= B.length < min(100000, N)
15+
# [0, N) does NOT include N. See interval notation.
16+
# Example 1:
17+
#
18+
# Input:
19+
# ["Solution","pick","pick","pick"]
20+
# [[1,[]],[],[],[]]
21+
# Output: [null,0,0,0]
22+
# Example 2:
23+
#
24+
# Input:
25+
# ["Solution","pick","pick","pick"]
26+
# [[2,[]],[],[],[]]
27+
# Output: [null,1,1,1]
28+
# Example 3:
29+
#
30+
# Input:
31+
# ["Solution","pick","pick","pick"]
32+
# [[3,[1]],[],[],[]]
33+
# Output: [null,0,0,2]
34+
# Example 4:
35+
#
36+
# Input:
37+
# ["Solution","pick","pick","pick"]
38+
# [[4,[2]],[],[],[]]
39+
# Output: [null,1,3,1]
40+
# Explanation of Input Syntax:
41+
#
42+
# The input is two lists: the subroutines called and
43+
# their arguments. Solution's constructor has two arguments,
44+
# N and the blacklist B.
45+
# pick has no arguments.
46+
# Arguments are always wrapped with a list,
47+
# even if there aren't any.
48+
49+
import random
50+
51+
LEFT, RIGHT, ACCU_COUNT = range(3)
52+
53+
54+
class Solution(object):
55+
56+
def __init__(self, N, blacklist):
57+
"""
58+
:type N: int
59+
:type blacklist: List[int]
60+
"""
61+
self.__n = N-len(blacklist)
62+
self.__intervals = []
63+
blacklist.sort()
64+
prev, count = 0, 0
65+
for black in blacklist:
66+
if prev != black:
67+
self.__intervals.append((prev, black, count))
68+
count += black-prev
69+
prev = black+1
70+
self.__intervals.append((prev, N, count))
71+
72+
def pick(self):
73+
"""
74+
:rtype: int
75+
"""
76+
index = random.randint(0, self.__n-1)
77+
left, right = 0, len(self.__intervals)-1
78+
while left <= right:
79+
mid = left+(right-left) // 2
80+
cur = self.__intervals[mid]
81+
if index < cur[ACCU_COUNT]+cur[RIGHT]-cur[LEFT]:
82+
right = mid-1
83+
else:
84+
left = mid+1
85+
return self.__intervals[left][LEFT] + \
86+
index - self.__intervals[left][ACCU_COUNT]
87+
88+
89+
# Your Solution object will be instantiated and called as such:
90+
# obj = Solution(N, blacklist)
91+
# param_1 = obj.pick()

0 commit comments

Comments
 (0)