497. 非重叠矩形中的随机点 ( presum+二分)
难度中等
给定一个由非重叠的轴对齐矩形的数组 rects
,其中 rects[i] = [ai, bi, xi, yi]
表示 (ai, bi)
是第 i
个矩形的左下角点,(xi, yi)
是第 i
个矩形的右上角点。设计一个算法来随机挑选一个被某一矩形覆盖的整数点。矩形周长上的点也算做是被矩形覆盖。所有满足要求的点必须等概率被返回。
在给定的矩形覆盖的空间内的任何整数点都有可能被返回。
请注意 ,整数点是具有整数坐标的点。
实现 Solution
类:
Solution(int[][] rects)
用给定的矩形数组rects
初始化对象。int[] pick()
返回一个随机的整数点[u, v]
在给定的矩形所覆盖的空间内。
示例 1:
输入: ["Solution", "pick", "pick", "pick", "pick", "pick"] [[[[-2, -2, 1, 1], [2, 2, 4, 6]]], [], [], [], [], []] 输出: [null, [1, -2], [1, -1], [-1, -2], [-2, -2], [0, 0]] 解释: Solution solution = new Solution([[-2, -2, 1, 1], [2, 2, 4, 6]]); solution.pick(); // 返回 [1, -2] solution.pick(); // 返回 [1, -1] solution.pick(); // 返回 [-1, -2] solution.pick(); // 返回 [-2, -2] solution.pick(); // 返回 [0, 0]
class Solution { public: vector<int> pre_area = {0}; vector<vector<int>> rects; Solution(vector<vector<int>>& rects) { this->rects = rects; for(auto rect: rects) { int area = pre_area.back() + (rect[2] - rect[0]+1) * (rect[3] - rect[1]+1); pre_area.emplace_back(area); } } int find_right(vector<int>& pre_area,int target) { int low = 0, high = pre_area.size(); while(low < high) { int mid = low + (high - low) / 2; if (pre_area[mid] < target) { low = mid + 1; } else { high = mid; } } return low; } vector<int> pick() { int tt = rand()% pre_area.back() + 1; int index_a = find_right(pre_area,tt); auto rect = rects[index_a-1]; // rand() % (b-a+1)+ a ; 就表示 a~b 之间的一个随机整数 int res1 = rand() % (rect[2]-rect[0]+1)+ rect[0]; int res2 = rand() % (rect[3]-rect[1]+1)+ rect[1]; vector<int> res = {res1,res2}; return res; } }; /** * Your Solution object will be instantiated and called as such: * Solution* obj = new Solution(rects); * vector<int> param_1 = obj->pick(); */