ID | Title | Difficulty | |
---|---|---|---|
Loading... |
497. Random Point in Non-overlapping Rectangles
Medium
LeetCode
Array, Math, Binary Search, Reservoir Sampling, Prefix Sum, Ordered Set, Randomized
Problem
You are given an array of non-overlapping axis-aligned rectangles rects where rects[i] = [ai, bi, xi, yi] indicates that (ai, bi) is the bottom-left corner point of the ith rectangle and (xi, yi) is the top-right corner point of the ith rectangle. Design an algorithm to pick a random integer point inside the space covered by one of the given rectangles. A point on the perimeter of a rectangle is included in the space covered by the rectangle.
Any integer point inside the space covered by one of the given rectangles should be equally likely to be returned.
Note that an integer point is a point that has integer coordinates.
Implement the Solution class:
- Solution(int[][] rects) Initializes the object with the given rectangles rects.
- int[] pick() Returns a random integer point [u, v] inside the space covered by one of the given rectangles.
Example 1:
Input
["Solution", "pick", "pick", "pick", "pick", "pick"]
[[[[-2, -2, 1, 1], [2, 2, 4, 6]]], [], [], [], [], []]
Output
[null, [1, -2], [1, -1], [-1, -2], [-2, -2], [0, 0]]
Explanation
Solution solution = new Solution([[-2, -2, 1, 1], [2, 2, 4, 6]]);
solution.pick(); // return [1, -2]
solution.pick(); // return [1, -1]
solution.pick(); // return [-1, -2]
solution.pick(); // return [-2, -2]
solution.pick(); // return [0, 0]
Constraints:
- 1 <= rects.length <= 100
- rects[i].length == 4
- -10^9 <= ai < xi <= 10^9
- -10^9 <= bi < yi <= 10^9
- x_i - a_i <= 2000
- y_i - b_i <= 2000
- All the rectangles do not overlap.
- At most 10^4 calls will be made to pick.
Code
class Solution {
TreeMap<Integer, Integer> map;
int[][] rects;
int sum;
Random rand;
public Solution(int[][] rects) {
this.rects = rects;
this.rand = new Random();
map = new TreeMap<>();
sum = 0;
for(int i = 0; i < rects.length; i++) {
int[] rect = rects[i];
// how many points
sum += (rect[2] - rect[0] + 1) * (rect[3] - rect[1] + 1);
map.put(sum, i);
}
}
public int[] pick() {
int c = map.ceilingKey(rand.nextInt(sum) + 1);
return pickInRect(rects[map.get(c)]);
}
private int[] pickInRect(int[] rect) {
int left = rect[0];
int right = rect[2];
int bottom = rect[1];
int top = rect[3];
return new int[]{left + rand.nextInt(right - left + 1), bottom + rand.nextInt(top - bottom + 1) };
}
}
按 <- 键看上一题!
496. Next Greater Element I
按 -> 键看下一题!
498. Diagonal Traverse