Random Point in Non-overlapping Rectangles
Given a list of non-overlapping axis-aligned rectangles rects
, write a function pick
which randomly and uniformily picks an integer point in the space covered by the rectangles.
Note:
An integer point is a point that has integer coordinates.
A point on the perimeter of a rectangle is included in the space covered by the rectangles.
i
th rectangle =rects[i]
=[x1,y1,x2,y2]
, where[x1, y1]
are the integer coordinates of the bottom-left corner, and[x2, y2]
are the integer coordinates of the top-right corner.length and width of each rectangle does not exceed
2000
.1 <= rects.length <= 100
pick
return a point as an array of integer coordinates[p_x, p_y]
pick
is called at most10000
times.
Example 1:
Input:
["Solution","pick","pick","pick"]
[[[[1,1,5,5]]],[],[],[]]
Output:
[null,[4,1],[4,1],[3,3]]
Example 2:
Input:
["Solution","pick","pick","pick","pick","pick"]
[[[[-2,-2,-1,-1],[1,0,3,0]]],[],[],[],[],[]]
Output:
[null,[-1,-2],[2,0],[-2,-1],[3,0],[-2,-2]]
Explanation of Input Syntax:
The input is two lists: the subroutines called and their arguments. Solution
's constructor has one argument, the array of rectangles rects
. pick
has no arguments. Arguments are always wrapped with a list, even if there aren't any.
Solutions
🧠 Cpp
#include <cstdlib>
#include <cmath>
#include <time.h>
class Solution
{
struct rect_info
{
const size_t start, end;
const int length, height;
vector<int>& rect;
};
size_t total_num_of_points = 0;
vector<vector<int>>& _rects;
vector<rect_info> _rect_infos;
public:
Solution(vector<vector<int>>& rects) : _rects(rects)
{
srand(time(NULL));
for(auto &rect : _rects)
{
const int
length = abs(rect[2] - rect[0]), //x2 - x1
height = abs(rect[3] - rect[1]); //y2 - y1
size_t rec_num_of_points = (length+1)*(height+1);
_rect_infos.push_back({total_num_of_points, total_num_of_points + rec_num_of_points,
length, height, rect});
total_num_of_points += rec_num_of_points;
}
}
vector<int> pick()
{
//select random rect
size_t point_index = rand()%total_num_of_points;
rect_info *ri = nullptr;
for(auto &r_info : _rect_infos)
{
if(r_info.start <= point_index && point_index < r_info.end)
{
ri = &r_info;
break;
}
}
//select random point
const int
x_offset = ri->length ? rand()%(ri->length+1) : 0,
y_offset = ri->height ? rand()%(ri->height+1) : 0;
return { ri->rect[0] + x_offset, ri->rect[1] + y_offset};
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(rects);
* vector<int> param_1 = obj->pick();
*/
Last updated
Was this helpful?