【LeetCode】478. Generate Random Point in a Circle 解题报告(Python)
作者: 负雪明烛
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(随机)
时间复杂度是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()
参考资料:
https://zhanghuimeng.github.io/post/leetcode-478-generate-random-point-in-a-circle/
日期
2018 年 10 月 14 日 —— 周赛做出来3个题,开心