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();
 */

 

posted @ 2022-08-25 21:01  乐乐章  阅读(56)  评论(0编辑  收藏  举报