Problem Description
Design an algorithm to pick a random integer point inside the space covered by one of the given non-overlapping axis-aligned rectangles. Each rectangle is defined by its bottom-left corner (a, b) and its top-right corner (x, y). Every integer point inside a rectangle, including those on its perimeter, should be equally likely to be chosen.
Key Insights
- Calculate the number of integer points inside each rectangle as (x - a + 1) * (y - b + 1).
- Build a prefix sum array over these counts to enable weighted random selection of a rectangle.
- Use binary search on the prefix sum array to quickly identify which rectangle a randomly generated integer point belongs to.
- Once a rectangle is selected, randomly pick a point within its boundaries.
Space and Time Complexity
Time Complexity:
- Preprocessing: O(n) where n is the number of rectangles.
- Each pick operation: O(log n) due to the binary search.
Space Complexity:
- O(n) for storing the prefix sums and the input rectangles.
Solution
The solution involves two main steps:
- Preprocess the list of rectangles by calculating and storing a cumulative count of integer points. This cumulative or prefix sum array allows us to determine which rectangle a randomly selected point falls into.
- For each call to pick(), generate a random integer in the range [1, total number of points]. Use binary search on the prefix sum array to determine the rectangle corresponding to that random integer. Then, pick a random x-coordinate and a random y-coordinate within that rectangle’s boundaries. This approach guarantees that each integer point across all rectangles is selected with equal probability.