Skip to content

Commit fe52cc8

Browse files
authored
Create random-point-in-non-overlapping-rectangles.py
1 parent 790b50a commit fe52cc8

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Time: O(logn)
2+
# Space: O(n)
3+
4+
# Given a list of non-overlapping axis-aligned rectangles rects,
5+
# write a function pick which randomly and uniformily picks
6+
# an integer point in the space covered by the rectangles.
7+
#
8+
# Note:
9+
# - An integer point is a point that has integer coordinates.
10+
# - A point on the perimeter of a rectangle is included in the space covered by the rectangles.
11+
# - ith rectangle = rects[i] = [x1,y1,x2,y2],
12+
# where [x1, y1] are the integer coordinates of the bottom-left corner,
13+
# and [x2, y2] are the integer coordinates of the top-right corner.
14+
# - length and width of each rectangle does not exceed 2000.
15+
# - 1 <= rects.length <= 100
16+
# - pick return a point as an array of integer coordinates [p_x, p_y]
17+
# - pick is called at most 10000 times.
18+
#
19+
# Example 1:
20+
#
21+
# Input:
22+
# ["Solution","pick","pick","pick"]
23+
# [[[[1,1,5,5]]],[],[],[]]
24+
# Output:
25+
# [null,[4,1],[4,1],[3,3]]
26+
# Example 2:
27+
#
28+
# Input:
29+
# ["Solution","pick","pick","pick","pick","pick"]
30+
# [[[[-2,-2,-1,-1],[1,0,3,0]]],[],[],[],[],[]]
31+
# Output:
32+
# [null,[-1,-2],[2,0],[-2,-1],[3,0],[-2,-2]]
33+
# Explanation of Input Syntax:
34+
#
35+
# The input is two lists: the subroutines called and their arguments.
36+
# Solution's constructor has one argument,
37+
# the array of rectangles rects. pick has no arguments.
38+
# Arguments are always wrapped with a list, even if there aren't any.
39+
40+
import random
41+
import bisect
42+
43+
44+
class Solution(object):
45+
46+
def __init__(self, rects):
47+
"""
48+
:type rects: List[List[int]]
49+
"""
50+
self.__rects = list(rects)
51+
self.__prefix_sum = map(lambda x : (x[2]-x[0]+1)*(x[3]-x[1]+1), rects)
52+
for i in xrange(1, len(self.__prefix_sum)):
53+
self.__prefix_sum[i] += self.__prefix_sum[i-1]
54+
55+
def pick(self):
56+
"""
57+
:rtype: List[int]
58+
"""
59+
target = random.randint(0, self.__prefix_sum[-1]-1)
60+
left = bisect.bisect_right(self.__prefix_sum, target)
61+
rect = self.__rects[left]
62+
width = rect[2]-rect[0]+1
63+
height = rect[3]-rect[1]+1
64+
base = self.__prefix_sum[left]-width*height
65+
return [rect[0]+(target-base)%width, rect[1]+(target-base)//width]
66+
67+
68+
# Your Solution object will be instantiated and called as such:
69+
# obj = Solution(rects)
70+
# param_1 = obj.pick()

0 commit comments

Comments
 (0)