Continue a criar, acelere o crescimento! Este é o 12º dia da minha participação no "Nuggets Daily New Plan · June Update Challenge", clique para ver os detalhes do evento
Descrição do tópico
Este é o LeetCode 478. Gere pontos aleatoriamente dentro de um círculo com dificuldade média .
Tag: "matemática", "randomização"
Dado o raio do círculo e a localização do centro do círculo, implemente a função randPoint
para gerar pontos aleatórios uniformes no círculo.
Classe de implementação Solution
:
Solution(double radius, double x_center, double y_center)
Use o raioradius
do círculo e a posição do centro do círculo inicializa o objetorandPoint()
Retorna um ponto aleatório dentro do círculo. Um ponto na circunferência é considerado dentro do círculo. As respostas são retornadas como uma matriz 。
Exemplo 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
复制代码
dica:
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};
}
}
复制代码
- 时间复杂度:
- 空间复杂度:
最后
Este é o primeiro No.478
artigo série começa em 01/01/2021. Na data de início, existem 1916 perguntas sobre LeetCode, algumas das quais estão bloqueadas. Primeiro, colocaremos todas as perguntas sem travas Tópico finalizado.
Nesta série de artigos, além de explicar as ideias de resolução de problemas, o código mais conciso será fornecido o máximo possível. Se soluções gerais estiverem envolvidas, os modelos de código correspondentes também serão fornecidos.
Para facilitar aos alunos a depuração e envio de código no computador, estabeleci um repositório relacionado: github.com/SharingSour… .
No endereço do armazém, você pode ver o link para a solução da série de artigos, o código correspondente da série de artigos, o link para a pergunta original do LeetCode e outras soluções preferidas.