계속 만들고 성장을 가속화하십시오! "너겟 데일리 뉴플랜 · 6월 업데이트 챌린지" 참여 12일차 입니다 . 이벤트 상세보기 클릭
주제 설명
LeetCode에서 478입니다. 중간 난이도 의 원 안에 무작위로 점을 생성합니다 .
태그 : "수학", "무작위화"
원의 반지름과 원의 중심 위치가 주어지면 원에 randPoint
균일한 임의의 점을 생성하는 함수를 구현합니다.
구현 Solution
클래스:
Solution(double radius, double x_center, double y_center)
원 의 반지름radius
과 원의 중심 위치를 사용 객체를 초기화합니다randPoint()
원 내부의 임의의 점을 반환합니다. 원주의 한 점은 원 안에 있는 것으로 간주됩니다. 답변은 배열로 반환됩니다. 。
예 1:
输入:
["Solution","randPoint","randPoint","randPoint"]
[[1.0, 0.0, 0.0], [], [], []]
输出: [null, [-0.02493, -0.38077], [0.82314, 0.38945], [0.36572, 0.17248]]
解释:
Solution solution = new Solution(1.0, 0.0, 0.0);
solution.randPoint ();//返回[-0.02493,-0.38077]
solution.randPoint ();//返回[0.82314,0.38945]
solution.randPoint ();//返回[0.36572,0.17248
复制代码
힌트:
randPoint
最多被调用 次
等概率随机采样
为了方便,我们称圆心为 ,半径为 。
对给定圆内的点进行等概率随机采样,容易想到随机化两个信息:一个是距离圆心的距离 len
(在范围
中进行随机),另外一个是夹角 ang
(在范围
中随机,随便找个参考线即可,例如以往
轴正方向的射线为参考)。
然后根据 len
和 ang
直接计算对应的点的坐标,这样 可以确保随机出来的点一定在圆内,但并非「等概率」。
在不考虑夹角的情况下,我们本质是在 范围内随机,这在「一维」上「等概率」是成立的,因为满足「任意连续段中点被抽到的次数与总次数的比例」与「该连续段长度与总长度的比例」。
但在圆中并非如此,不考虑夹角时,「任意连续段 len
与总长度 r
的比例」和「len
对应面积与总面积比例」并不相等。例如 len
有
的概率取到小于等于
的值,而半径为
扫过的面积仅为总面积的
,因此我们的 len
不能直接在
范围内随机,为了消除这种一维转圆导致的「等概率」失效,我们可以从
内随机再开平方,从而确保距离与面积比例一致。
代码:
class Solution {
double r, x, y;
Random random = new Random();
public Solution(double _r, double _x, double _y) {
r = _r; x = _x; y = _y;
}
public double[] randPoint() {
double len = Math.sqrt(random.nextDouble(r * r)), ang = random.nextDouble(2 * Math.PI);
double nx = x + len * Math.cos(ang), ny = y + len * Math.sin(ang);
return new double[]{nx, ny};
}
}
复制代码
- 时间复杂度:
- 空间复杂度:
最后
这是我们「刷穿 LeetCode」系列文章的第 No.478
篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
이 일련의 기사에서는 문제 해결 아이디어를 설명하는 것 외에도 가장 간결한 코드를 최대한 많이 제공합니다. 일반 솔루션이 포함된 경우 해당 코드 템플릿도 제공됩니다.
학생들이 컴퓨터에서 코드를 디버그하고 제출하는 것을 용이하게 하기 위해 관련 저장소를 만들었습니다. github.com/SharingSour… .
창고 주소에서 일련의 기사 솔루션에 대한 링크, 기사 시리즈의 해당 코드, LeetCode의 원래 질문에 대한 링크 및 기타 선호하는 솔루션에 대한 링크를 볼 수 있습니다.