478. Generate Random Point in a Circle
leetcode medium
Task
Дан радиус и положение центра окружности, реализуйте функцию randPoint, которая генерирует равномерно случайную точку внутри окружности.
Реализуйте класс Solution:
- Solution(double radius, double x_center, double y_center) инициализирует объект с радиусом окружности radius и положением центра (x_center, y_center).
- randPoint() возвращает случайную точку внутри окружности. Точка на окружности считается находящейся внутри окружности. Ответ возвращается в виде массива [x, y].
Пример:
Input
["Solution", "randPoint", "randPoint", "randPoint"]
[[1.0, 0.0, 0.0], [], [], []]
Output
[null, [-0.02493, -0.38077], [0.82314, 0.38945], [0.36572, 0.17248]]
Explanation
Solution solution = new Solution(1.0, 0.0, 0.0);
solution.randPoint(); // return [-0.02493, -0.38077]
solution.randPoint(); // return [0.82314, 0.38945]
solution.randPoint(); // return [0.36572, 0.17248]
C# solution
matched/originalusing System;
public class Solution {
double rad, xc, yc;
public Solution(double radius, double x_center, double y_center) {
rad = radius;
xc = x_center;
yc = y_center;
}
public double[] RandPoint() {
double x0 = xc - rad;
double y0 = yc - rad;
while (true) {
double xg = x0 + new Random().NextDouble() * rad * 2;
double yg = y0 + new Random().NextDouble() * rad * 2;
if (Math.Sqrt(Math.Pow(xg - xc, 2) + Math.Pow(yg - yc, 2)) <= rad) {
return new double[] { xg, yg };
}
}
}
}C++ solution
auto-draft, review before submit#include <bits/stdc++.h>
using namespace std;
// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
double rad, xc, yc;
public Solution(double radius, double x_center, double y_center) {
rad = radius;
xc = x_center;
yc = y_center;
}
public double[] RandPoint() {
double x0 = xc - rad;
double y0 = yc - rad;
while (true) {
double xg = x0 + new Random().NextDouble() * rad * 2;
double yg = y0 + new Random().NextDouble() * rad * 2;
if (Math.Sqrt(Math.Pow(xg - xc, 2) + Math.Pow(yg - yc, 2)) <= rad) {
return new double[] { xg, yg };
}
}
}
}Java solution
matched/originalclass Solution {
double rad, xc, yc;
public Solution(double radius, double x_center, double y_center) {
rad = radius;
xc = x_center;
yc = y_center;
}
public double[] randPoint() {
double x0 = xc - rad;
double y0 = yc - rad;
while (true) {
double xg = x0 + Math.random() * rad * 2;
double yg = y0 + Math.random() * rad * 2;
if (Math.sqrt(Math.pow((xg - xc), 2) + Math.pow((yg - yc), 2)) <= rad) {
return new double[]{xg, yg};
}
}
}
}JavaScript solution
matched/originalclass Solution {
constructor(radius, x_center, y_center) {
this.rad = radius;
this.xc = x_center;
this.yc = y_center;
}
randPoint() {
const x0 = this.xc - this.rad;
const y0 = this.yc - this.rad;
while (true) {
const xg = x0 + Math.random() * this.rad * 2;
const yg = y0 + Math.random() * this.rad * 2;
if (Math.sqrt(Math.pow(xg - this.xc, 2) + Math.pow(yg - this.yc, 2)) <= this.rad) {
return [xg, yg];
}
}
}
}Python solution
matched/originalimport random
import math
class Solution:
def __init__(self, radius: float, x_center: float, y_center: float):
self.rad = radius
self.xc = x_center
self.yc = y_center
def randPoint(self) -> List[float]:
x0, y0 = self.xc - self.rad, self.yc - self.rad
while True:
xg = x0 + random.random() * self.rad * 2
yg = y0 + random.random() * self.rad * 2
if math.sqrt((xg - self.xc) ** 2 + (yg - self.yc) ** 2) <= self.rad:
return [xg, yg]Go solution
matched/originalpackage main
import (
"math"
"math/rand"
"time"
)
type Solution struct {
rad, xc, yc float64
}
func Constructor(radius float64, x_center float64, y_center float64) Solution {
rand.Seed(time.Now().UnixNano())
return Solution{rad: radius, xc: x_center, yc: y_center}
}
func (s *Solution) RandPoint() []float64 {
x0 := s.xc - s.rad
y0 := s.yc - s.rad
for {
xg := x0 + rand.Float64()*s.rad*2
yg := y0 + rand.Float64()*s.rad*2
if math.Sqrt(math.Pow(xg-s.xc, 2)+math.Pow(yg-s.yc, 2)) <= s.rad {
return []float64{xg, yg}
}
}
}Explanation
Algorithm
Генерируем равномерно случайные точки в квадрате S с длиной стороны 2R.
Сохраняем все точки, которые находятся на расстоянии не более R от центра, и отклоняем все, которые дальше этого расстояния.
Повторяем процесс до получения нужного количества точек, учитывая, что примерно 78.5% от всех сгенерированных точек будут приемлемыми, и ожидаемое число попыток до получения приемлемой точки составляет примерно 1.274 раза.
😎