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:

  1. An integer point is a point that has integer coordinates.
  2. A point on the perimeter of a rectangle is included in the space covered by the rectangles.
  3. ith 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.
  4. length and width of each rectangle does not exceed 2000.
  5. 1 <= rects.length <= 100
  6. pick return a point as an array of integer coordinates [p_x, p_y]
  7. pick is called at most 10000 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 rectspick has no arguments. Arguments are always wrapped with a list, even if there aren't any.

这道题给了我们一些非重叠的矩形,让我们返回一个这些矩形中的一个随机的点。那么博主的第一直觉就是首先要在这些矩形中随机挑出来一个,然后在这个随机的矩形中再随机生成一个点,通过随机生成一个长和宽即可。博主最开始想到的方法是用rand随机生成一个 [0, n) 范围内的数字,n为输入矩形的个数,这样就得到了一个随机的矩形。但是这种方法貌似行不通,会跪在一个很长的输入测试数据。这使得博主比较困惑了,没有想出原因是为何,有哪位看官大神们知道的,麻烦留言告知博主哈!哈,已经知道了,参见评论区二楼留言~ 论坛上的解法有一种是用水塘抽样Reservoir Sampling的方法的,LeetCode之前有过几道需要用这种方法的题目 Random Pick IndexShuffle an Array 和 Linked List Random Node。这里我们使用其来随机出一个矩形,做法是遍历所有的矩形,用变量sumArea来计算当前遍历过的所有矩形面积之和,然后变量area是当前遍历的矩形的面积(注意这里不是严格意义上的面积,而是该区域内整数坐标的点的个数,所以长宽相乘的时候都要加1),然后我们在当前所有矩形面积之和内随机生成一个值,如果这个值小于area,那么选择当前的矩阵为随机矩形。这里相当于一个大小为area的水塘,在这个值之内的话,就更换selected。这个方法是没啥问题,但是博主还是没想通为啥不能直接随机生成矩形的index。当我们拿到随机矩形后,之后就随机出宽和高返回即可,参见代码如下:

解法一:

class Solution {
public:
Solution(vector<vector<int>> rects) {
_rects = rects;
} vector<int> pick() {
int sumArea = ;
vector<int> selected;
for (auto rect : _rects) {
int area = (rect[] - rect[] + ) * (rect[] - rect[] + );
sumArea += area;
if (rand() % sumArea < area) selected = rect;
}
int x = rand() % (selected[] - selected[] + ) + selected[];
int y = rand() % (selected[] - selected[] + ) + selected[];
return {x, y};
} private:
vector<vector<int>> _rects;
};

这道题在论坛上的主流解法其实是这个,我们用TreeMap来建立当前遍历过的矩形面积之和跟该矩形位置之间的映射。然后当我们求出所有的矩形面积之和后,我们随机生成一个值,然后在TreeMap中找到第一个大于这个值的矩形,这里博主还是有疑问,为啥不能直接随机矩形的位置,而是非要跟面积扯上关系。之后的步骤就跟上面的没啥区别了,参见代码如下:

解法二:

class Solution {
public:
Solution(vector<vector<int>> rects) {
_rects = rects;
_totalArea = ;
for (auto rect : rects) {
_totalArea += (rect[] - rect[] + ) * (rect[] - rect[] + );
_areaToIdx.insert({_totalArea, _areaToIdx.size()});
}
} vector<int> pick() {
int val = rand() % _totalArea;
int idx = _areaToIdx.upper_bound(val)->second;
int width = _rects[idx][] - _rects[idx][] + ;
int height = _rects[idx][] - _rects[idx][] + ;
return {rand() % width + _rects[idx][], rand() % height + _rects[idx][]};
} private:
vector<vector<int>> _rects;
int _totalArea;
map<int, int> _areaToIdx;
};

类似题目:

Random Pick with Weight

Generate Random Point in a Circle

参考资料:

https://leetcode.com/problems/random-point-in-non-overlapping-rectangles/

https://leetcode.com/problems/random-point-in-non-overlapping-rectangles/discuss/155005/C%2B%2B-single-rand()-call

https://leetcode.com/problems/random-point-in-non-overlapping-rectangles/discuss/169185/Short-C%2B%2B-solution-with-upper_bound

https://leetcode.com/problems/random-point-in-non-overlapping-rectangles/discuss/170503/C%2B%2B-solution-using-reservoir-sampling-with-explanation-concise-and-easy-to-understand

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Random Point in Non-overlapping Rectangles 非重叠矩形中的随机点的更多相关文章

  1. [Swift]LeetCode497. 非重叠矩形中的随机点 | Random Point in Non-overlapping Rectangles

    Given a list of non-overlapping axis-aligned rectangles rects, write a function pick which randomly ...

  2. 2017ICPC南宁赛区网络赛 Overlapping Rectangles(重叠矩阵面积和=离散化模板)

    There are nnn rectangles on the plane. The problem is to find the area of the union of these rectang ...

  3. [Swift]LeetCode1031. 两个非重叠子数组的最大和 | Maximum Sum of Two Non-Overlapping Subarrays

    Given an array A of non-negative integers, return the maximum sum of elements in two non-overlapping ...

  4. 在ASP.NET非MVC环境中(WebForm中)构造MVC的URL参数

    目前项目中有个需求,需要在WebForm中去构造MVC的URL信息,这里写了一个帮助类可以在ASP.NET非MVC环境中(WebForm中)构造MVC的URL信息,主要就是借助当前Http上下文去构造 ...

  5. Android 高级UI设计笔记17:Android在非UI线程中显示Toast

    1. 子线程的Toast怎么显示不出来? 因为Toast在创建的时候会依赖于一个Handler,并且一个Handler是需要有一个Looper才能够创建,而普通的线程是不会自动去创建一个Looper对 ...

  6. leetcode 题解:Binary Tree Inorder Traversal (二叉树的中序遍历)

    题目: Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary ...

  7. 在非MFC程序中引用CString

    CString在当今软件设计界里还是小有名气的,说它是MFC中使用的最多的类一点也不过,然而在使用sdk编windows程序的时候,确不能利用CString类,只能用sdk的运行时库,比如strlen ...

  8. 如何在非 React 项目中使用 Redux

    本文作者:胡子大哈 原文链接:https://scriptoj.com/topic/178/如何在非-react-项目中使用-redux 转载请注明出处,保留原文链接和作者信息. 目录 1.前言 2. ...

  9. 关于C#中”扩展方法必须在非泛型静态类中定义“问题的解决

    问题描述: 在某个窗口下的编码中使用了以下扩展方法FindControl,以求根据字符串的值去操作控件(本文中的控件为Label控件)的属性. public static Control FindCo ...

随机推荐

  1. HDU 5984(求木棒切割期望 数学)

    题意是给定一长为 L 的木棒,每次任意切去一部分直到剩余部分的长度不超过 D,求切割次数的期望. 若木棒初始长度不超过 D,则期望是 0.000000: 设切割长度为 X 的木棒切割次数的期望是 F( ...

  2. 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性)

    一. 简介 上一个章节中,也介绍了立即加载和延迟加载,但上一个章节是针对单表而言的,不含外键,立即也好,延迟也好,都是指单表中的数据.但本章节重点介绍的三种加载方式均是针对含(导航属性.外键)的情况下 ...

  3. 第七节:语法总结(1)(自动属性、out参数、对象初始化器、var和dynamic等)

    一. 语法糖简介   语法糖也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方 ...

  4. luogu 3084 单调队列+dp

    注意处理出两个数组: r[i] 能覆盖i点的区间的左端点最小值(覆盖左侧最远处) l[i] i不能覆盖的区间的左端点左端点最大值 在该区间内寻找用来更新f[i] 答案的 j 即 l[i]<= j ...

  5. C#控件数组批量生成控件

    在编写C#窗体应用程序的时候,有时候需要生成好多个功能相似的同一种控件(比如数字键盘按键.单选框等),这时候使用窗体编辑器,费时费力,不便于修改.因此可以采用批量生成控件的形式. 以批量生成按钮为例 ...

  6. Re-enable extensions not coming from Chrome Web Store on Chrome v35+ (with enhanced security)

    1. Add the --enable-easy-off-store-extension-install flag when you start chrome (create shortcut, ed ...

  7. sed 使用行号与关键字匹配限定行范围

    1.打印匹配数字4 到最后一行 [111 sed]$ cat input [111 sed]$ sed -n '/4/,$p' input

  8. sklearn.linear_model.LinearRegresion学习

    sklearn线性模型之线性回归 查看官网 https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearR ...

  9. Flask开发微电影网站(八)

    1.后台管理之电影预告管理 1.1 定义电影预告表单 在app的admin目录的forms.py文件中,定义电影预告表单 # 预告表单 class PreviewForm(FlaskForm): ti ...

  10. django-admin.py startproject testdj 失败 没有工程文件夹

    今天第一次用django创建工程时一直没有反应,没有期望的文件夹出现 第一种:网上查找了一下,发现是因为py文件的默认打开不是python.exe,而是编辑器 解决方法:先随便找一个py文件,点击右键 ...