【LeetCode】478. Generate Random Point in a Circle 解题报告(Python & C++)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址: https://leetcode.com/problems/generate-random-point-in-a-circle/description/
题目描述:
Given the radius and x-y positions of the center of a circle, write a function randPoint
which generates a uniform random point in the circle.
Note:
- input and output values are in floating-point.
- radius and x-y position of the center of the circle is passed into the class constructor.
- a point on the circumference of the circle is considered to be in the circle.
randPoint
returns a size 2 array containing x-position and y-position of the random point, in that order.
Example 1:
Input:
["Solution","randPoint","randPoint","randPoint"]
[[1,0,0],[],[],[]]
Output: [null,[-0.72939,-0.65505],[-0.78502,-0.28626],[-0.83119,-0.19803]]
Example 2:
Input:
["Solution","randPoint","randPoint","randPoint"]
[[10,5,-7.5],[],[],[]]
Output: [null,[11.52438,-8.33273],[2.46992,-16.21705],[11.13430,-12.42337]]
Explanation of Input Syntax:
The input is two lists: the subroutines called and their arguments. Solution’s constructor has three arguments, the radius, x-position of the center, and y-position of the center of the circle. randPoint has no arguments. Arguments are always wrapped with a list, even if there aren’t any.
题目大意
给定圆的圆心和半径,生成落在这个圆里面的随机点。
解题方法
比较简单的方法是拒绝采样(Rejection Sampling),先在圆的外接圆内随机采点,然后判断这个点是不是在圆内,如果是的话就返回,否则再取一次。这个方法还可以用来估计圆周率。方法就不写了。
我直觉的方法还是使用极坐标的方式,随机找半径、随机找角度,然后就确定了一个点。但是没有通过最后一个测试用例。如果不查资料我是不会发现,这个做法是错的!
直接对半径和角度进行随机采样的方式会使得靠近圆心的点被取到的概率偏大,结果是取点的概率在这个圆内不是均匀的。为什么呢?因为题目要求的是对圆内任何面积上的点是均匀分布的,而不是对圆心出发的半径上是均匀分布的。那么以圆心为半径的小圆的范围内的点密度一定会比更大圆的密度大。
下图中左侧是随机生成半径和角度构成的点,右侧是随即生成的半径取根号和角度构成的点。
正确的做法是对边的随机数求根号。具体做法需要看478. Generate Random Point in a Circle(随机)
那么这个事情应该怎么理解呢?
首先我们要明白,题目要我们产生的是在圆内产生均匀的点,也就是说,对于圆中任意小的面积内落入点的概率相等。注意刚才说的是任意面积落点的概率是相等的。而如果采用随机半径+随机角度的方式,那么在任意半径上落入点的概率相等。很明显的是靠近圆心的半径比较密,远离圆心的时候半径比较稀疏。(类比一下太阳,太阳表面光线密度最大也就最亮,随着光线的传播,距离越远,光的亮度越小。)
右图这种对半径去根号的为什么是对的呢?因为我们产生的随机数是在0~1之间,那么去了根号之后会使得生成的点在1附近的密度更大,在0附近的密度变小。直觉上来看,那就是使得半径最外边被取到的概率变大,在圆心附近被取到的概率变小了。从而修正了圆心取到的点更密集的问题。
时间复杂度是O(1),空间复杂度是O(1)。
class Solution:
def __init__(self, radius, x_center, y_center):
"""
:type radius: float
:type x_center: float
:type y_center: float
"""
self.r = radius
self.x = x_center
self.y = y_center
def randPoint(self):
"""
:rtype: List[float]
"""
nr = math.sqrt(random.random()) * self.r
alpha = random.random() * 2 * 3.141592653
newx = self.x + nr * math.cos(alpha)
newy = self.y + nr * math.sin(alpha)
return [newx, newy]
# Your Solution object will be instantiated and called as such:
# obj = Solution(radius, x_center, y_center)
# param_1 = obj.randPoint()
C++代码如下:
class Solution {
public:
Solution(double radius, double x_center, double y_center) {
rad = radius;
x = x_center;
y = y_center;
}
vector<double> randPoint() {
const double PI = 3.141592653;
double nr = sqrt(rand() / double(RAND_MAX)) * rad;
double alpha = rand() / double(RAND_MAX) * 2 * PI;
double nx = x + nr * cos(alpha);
double ny = y + nr * sin(alpha);
return {nx, ny};
}
private:
double rad;
double x, y;
};
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(radius, x_center, y_center);
* vector<double> param_1 = obj.randPoint();
*/
参考资料:
https://zhanghuimeng.github.io/post/leetcode-478-generate-random-point-in-a-circle/
日期
2018 年 10 月 14 日 —— 周赛做出来3个题,开心
2019 年 2 月 1 日 —— 2019已经过去了一个月
【LeetCode】478. Generate Random Point in a Circle 解题报告(Python & C++)的更多相关文章
- 478. Generate Random Point in a Circle
1. 问题 给定一个圆的半径和圆心坐标,生成圆内点的坐标. 2. 思路 简单说 (1)在圆内随机取点不好做,但是如果画出这个圆的外接正方形,在正方形里面采样就好做了. (2)取两个random确定正方 ...
- 【LeetCode】497. Random Point in Non-overlapping Rectangles 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/random-p ...
- 【LeetCode】26. Remove Duplicates from Sorted Array 解题报告(Python&C++&Java)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 日期 [LeetCode] https:// ...
- 【LeetCode】450. Delete Node in a BST 解题报告 (Python&C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 迭代 日期 题目地址:https://leetcode ...
- 【LeetCode】380. Insert Delete GetRandom O(1) 解题报告(Python)
[LeetCode]380. Insert Delete GetRandom O(1) 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxu ...
- 【LeetCode】95. Unique Binary Search Trees II 解题报告(Python)
[LeetCode]95. Unique Binary Search Trees II 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzh ...
- 【LeetCode】Longest Word in Dictionary through Deleting 解题报告
[LeetCode]Longest Word in Dictionary through Deleting 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode. ...
- 【LeetCode】129. Sum Root to Leaf Numbers 解题报告(Python)
[LeetCode]129. Sum Root to Leaf Numbers 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/pr ...
- 【LeetCode】873. Length of Longest Fibonacci Subsequence 解题报告(Python)
[LeetCode]873. Length of Longest Fibonacci Subsequence 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: ...
随机推荐
- phpMyAdmin简介及安装
phpMyAdmin是一个MySQL数据库管理工具,通过Web接口管理数据库方便快捷. Linux系统安装phpMyAdmin phpMyAdmin是一个MySQL数据库管理工具,通过Web接口管理数 ...
- CMakeLists.txt添加多个源代码
coos2d-x 3.17.2 C++工程,安卓编译使用CMake,按照模板给的写法,只能一个一个源文件添加:如果需要添加大量的C++源代码,这种方式肯定不可取:原来的写法: 1 list(APPEN ...
- 学习java的第二十五天
一.今日收获 1.java完全学习手册第三章算法的3.2排序,比较了跟c语言排序上的不同 2.观看哔哩哔哩上的教学视频 二.今日问题 1.快速排序法的运行调试多次 2.哔哩哔哩教学视频的一些术语不太理 ...
- SpringBoot Profiles 多环境配置及切换
目录 前言 默认环境配置 多环境配置 多环境切换 小结 前言 大部分情况下,我们开发的产品应用都会根据不同的目的,支持运行在不同的环境(Profile)下,比如: 开发环境(dev) 测试环境(tes ...
- ceph块存储场景
1.创建rbd使用的存储池. admin节点需要安装ceph才能使用该命令,如果没有,也可以切换到ceph-node1节点去操作. [cephfsd@ceph-admin ceph]$ ceph os ...
- Spark的shuffle和MapReduce的shuffle对比
目录 MapperReduce的shuffle Spark的shuffle 总结 MapperReduce的shuffle shuffle阶段划分 Map阶段和Reduce阶段 任务 MapTask和 ...
- java.sql.SQLException: Cannot create com._51doit.pojo.User: com._51doit.pojo.User Query: select * from user where username = ? and password = ? Parameters: [AA, 123]
在从数据库中查询数据,并存入javabean中去时,报这个错误 原因:在建立User类去存储信息时没有创建无参构造方法,创建一个无参构造方法即可
- CR LF 的含义
可以参考: 转载于:https://www.cnblogs.com/babykick/archive/2011/03/25/1995977.html
- keil 生成 bin 文件 gd32为例
fromelf --bin --output .\update\GD32F4xZ.bin .\Output\GD32450Z_EVAL.axf代表使用的keil内的工具代表输出公式,..表示: 输出 ...
- Docker学习(五)——Docker仓库管理
Docker仓库管理 仓库(Repository)是集中存放镜像的地方. 1.Docker Hub 目前Docker官方维护了一个公共仓库Docker Hub.大部分需求都可以通过 ...