class Solution:
def __init__(self, rects: List[List[int]]):
self.rects = rects
self.weight = []
s = 0 # area of rectangula
for rect in self.rects:
area = (rect[2] - rect[0] + 1 ) * (rect[3] - rect[1] + 1 ) # to include edge of rectangular
s += area
self.weight.append(s)
def pick(self) -> List[int]:
idx = bisect.bisect_left(self.weight,random.randint(1,self.weight[-1]))
rect = self.rects[idx]
return [random.randint(rect[0],rect[2]),random.randint(rect[1],rect[3])]
refernce optimization to reduce random twice
class Solution(object):
def __init__(self, rects):
self.rects = rects
self.psum = []
self.sm = 0
for x1, y1, x2, y2 in self.rects:
area = (y2 - y1 + 1) * (x2 - x1 + 1)
self.sm += area
self.psum.append(self.sm)
def pick(self):
val = random.randint(0, self.sm - 1)
left, right = 0, len(self.psum)-1
while left < right:
mid = left + (right - left) // 2
if self.psum[mid] > val:
right = mid
else:
left = mid + 1
# chosen rectangle index is left
x1, y1, x2, y2 = self.rects[left]
height, width = y2 - y1 + 1, x2 - x1 + 1
base = self.psum[left] - height * width
x = x1 + (val - base) % width
y = y1 + (val - base) // width
return x, y