leetcode-在圆内随机生成点

152 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

题目描述

给定圆的半径和圆心的位置,实现函数 randPoint ,在圆中产生均匀随机点。

实现 Solution 类:

  • Solution(double radius, double x_center, double y_center) 用圆的半径 radius 和圆心的位置 (x_center, y_center) 初始化对象
  • randPoint() 返回圆内的一个随机点。圆周上的一点被认为在圆内。答案作为数组返回 [x, y] 。

示例 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]

思路

数学题目,一开始的思路是这样的:要在圆中随机取一点,就先扩大到以圆心为中心点的正方形,此时随机取一点在数学上实现是容易的,长和宽各自在范围内随机取值即可,然后再判断这个点是否在圆内,不在圆内就重新取,这样做概率是等概率的,就是复杂度有点高,陷入这种思路后,怎么都想不到怎么直接在圆内等概率直接取一点。
看了三叶姐的题解,发现挺有意思,先分成2个维度:

  1. 点到圆心的距离
  2. 点和x轴正方向的夹角 但是这2个维度分别取随机后,组合起来确不是整体的等概率随机,因为我们是在一个平面上取的,维度1取随机,有1/2的概率取到r/2以内的值,维度2全取的情况下,此时的面积只有整体的1/4。为了解决这个问题,三叶姐在维度1取随机的时候,范围不是[0,r],而是[0,r^2],取完再做一次开方,这样就保证了在平面上是等概率的。

Java版本代码

class Solution {

    private double r, x, y;

    private Random random;

    public Solution(double radius, double x_center, double y_center) {
        r = radius;
        x = x_center;
        y = y_center;
        random = new Random();
    }
    
    public double[] randPoint() {
        double l = Math.sqrt(random.nextDouble(r*r));
        double ang = random.nextDouble(2 * Math.PI);
        double rx = x + l * Math.cos(ang);
        double ry = y + l * Math.sin(ang);
        return new double[]{rx, ry};
    }
}