You are given the radius and the position of the center of a circle. Implement the function randPoint
which generates a uniform random point inside the circle.
Implement the Solution
class:
Solution(double radius, double x_center, double y_center)
initializes the object with the radius of the circle radius
and the position of the center (x_center, y_center)
. You can assume that 0 < radius <= 10^8
and -10^7 <= x_center, y_center <= 10^7
.randPoint()
returns a random point inside the circle. A point on the circumference of the circle is considered to be in the circle. The answer is returned as an array [x, y]
. You can assume that at most 3 * 10^4
calls will be made to randPoint
.For example, if we create a Solution
with radius = 1.0
, x_center = 0.0
, and y_center = 0.0
, some possible outputs of randPoint()
could be [-0.02493, -0.38077]
, [0.82314, 0.38945]
, or [0.36572, 0.17248]
. Note that these are just examples; the output should be a uniformly random point within the circle.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We need to pick a random spot inside a circle. The brute force way is like throwing darts randomly at a square that covers the whole circle, and then only keeping the darts that landed inside the circle.
Here's how the algorithm would work step-by-step:
import random
import math
class Solution:
def __init__(self, radius: float, x_center: float, y_center: float):
self.radius = radius
self.x_center = x_center
self.y_center = y_center
def generate(self) -> list[float]:
while True:
# Generate random x and y within the square bounds.
random_x = random.uniform(self.x_center - self.radius, self.x_center + self.radius)
random_y = random.uniform(self.y_center - self.radius, self.y_center + self.radius)
# Check if the point is within the circle.
distance_from_center = math.sqrt((random_x - self.x_center)**2 + (random_y - self.y_center)**2)
# If the point is inside the circle, return it.
if distance_from_center <= self.radius:
return [random_x, random_y]
# Your Solution object will be instantiated and called as such:
# obj = Solution(radius, x_center, y_center)
# param_1 = obj.generate()
The challenge is to pick random spots inside a circle fairly. The tricky part is realizing that if you pick the radius and angle separately and uniformly, you'll end up with points clustered towards the center. Instead, we need to pick the square of the radius to ensure an even spread.
Here's how the algorithm would work step-by-step:
import random
import math
class Solution:
def __init__(self, radius: float, x_center: float, y_center: float):
self.radius = radius
self.x_center = x_center
self.y_center = y_center
def randPoint(self):
# Generate the square of the radius for uniform sampling
squared_radius = random.random() * (self.radius ** 2)
# Calculate the actual radius
distance_from_center = math.sqrt(squared_radius)
# Generate a random angle
random_angle = random.random() * 2 * math.pi
# Calculate the x and y coordinates
x_coordinate = self.x_center + distance_from_center * math.cos(random_angle)
y_coordinate = self.y_center + distance_from_center * math.sin(random_angle)
return [x_coordinate, y_coordinate]
Case | How to Handle |
---|---|
Radius is zero | Return the center point (x, y) since that's the only valid point |
Radius is negative | Throw an IllegalArgumentException as radius should be non-negative |
Very large radius (close to the maximum floating-point value) | Ensure intermediate calculations (e.g., radius * random number) do not overflow or lose significant precision |
Center coordinates are extremely large or small | Ensure offsets from the center don't cause overflow or underflow problems during coordinate generation |
Floating-point precision errors causing infinite loop near the edge | Use Math.random() * radius carefully to avoid potential infinite loops from floating point comparison issues. |
Generating many points repeatedly | Ensure randomness of points does not degrade over many iterations |
Center point is at the origin (0, 0) | The algorithm handles the origin without modification as it functions the same mathematically. |
X and Y coordinates could have different scales (e.g., very large X and small Y) | The standard algorithm works as it is normalized to the radius. |