Alice is throwing n darts on a very large wall. You are given an array darts where darts[i] = [xi, yi] is the position of the ith dart that Alice threw on the wall.
Bob knows the positions of the n darts on the wall. He wants to place a dartboard of radius r on the wall so that the maximum number of darts that Alice throws lie on the dartboard.
Given the integer r, return the maximum number of darts that can lie on the dartboard.
Example 1:
Input: darts = [[-2,0],[2,0],[0,2],[0,-2]], r = 2 Output: 4 Explanation: Circle dartboard with center in (0,0) and radius = 2 contain all points.
Example 2:
Input: darts = [[-3,0],[3,0],[2,6],[5,4],[0,9],[7,8]], r = 5 Output: 5 Explanation: Circle dartboard with center in (0,4) and radius = 5 contain all points except the point (7,8).
Constraints:
1 <= darts.length <= 100darts[i].length == 2-104 <= xi, yi <= 104darts are unique1 <= r <= 5000When 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:
The brute force approach to this dartboard problem involves checking every possible circle location and seeing how many darts fall inside. We essentially try out all combinations to find the circle that captures the most darts. It's like drawing a circle on the dartboard over and over, each time in a slightly different spot, and counting the darts inside.
Here's how the algorithm would work step-by-step:
def max_darts_inside(darts, radius):
max_darts = 0
number_of_darts = len(darts)
for i in range(number_of_darts):
for j in range(i + 1, number_of_darts):
# Consider each pair of darts as potential circle centers.
center_x = (darts[i][0] + darts[j][0]) / 2
center_y = (darts[i][1] + darts[j][1]) / 2
darts_inside = 0
for k in range(number_of_darts):
distance = ((darts[k][0] - center_x) ** 2 + (darts[k][1] - center_y) ** 2) ** 0.5
# Count the darts within the radius of the center
if distance <= radius:
darts_inside += 1
max_darts = max(max_darts, darts_inside)
# Check each dart as a potential center point.
for i in range(number_of_darts):
center_x = darts[i][0]
center_y = darts[i][1]
darts_inside = 0
for j in range(number_of_darts):
distance = ((darts[j][0] - center_x) ** 2 + (darts[j][1] - center_y) ** 2) ** 0.5
if distance <= radius:
darts_inside += 1
max_darts = max(max_darts, darts_inside)
# Return the maximum number of darts within any circle
return max_dartsThe key idea is to try all possible pairs of points as potential centers of circles and count how many other points fall within a circle of the given radius centered at each candidate. By systematically checking pairs, we avoid examining every possible combination of three or more points to define a circle.
Here's how the algorithm would work step-by-step:
import math
def maximum_number_of_darts_inside(points, radius):
number_of_points = len(points)
if number_of_points <= 1:
return number_of_points
max_points_inside = 1
for i in range(number_of_points):
for j in range(i + 1, number_of_points):
point1_x, point1_y = points[i]
point2_x, point2_y = points[j]
# Calculate the distance between the two points.
distance_between_points = math.sqrt((point1_x - point2_x)**2 + (point1_y - point2_y)**2)
# If the distance is greater than 2 * radius, skip.
if distance_between_points > 2 * radius:
continue
# Calculate the midpoint between the two points.
midpoint_x = (point1_x + point2_x) / 2
midpoint_y = (point1_y + point2_y) / 2
# Calculate the distance from midpoint to center.
distance_to_center = math.sqrt(radius**2 - (distance_between_points / 2)**2)
# Calculate the center 1.
center1_x = midpoint_x + distance_to_center * (point1_y - point2_y) / distance_between_points
center1_y = midpoint_y + distance_to_center * (point2_x - point1_x) / distance_between_points
# Count the number of points inside the circle with center 1.
points_inside_center1 = 0
for k in range(number_of_points):
point_x, point_y = points[k]
distance_to_center1 = math.sqrt((point_x - center1_x)**2 + (point_y - center1_y)**2)
if distance_to_center1 <= radius:
points_inside_center1 += 1
max_points_inside = max(max_points_inside, points_inside_center1)
# Calculate the center 2.
center2_x = midpoint_x - distance_to_center * (point1_y - point2_y) / distance_between_points
center2_y = midpoint_y - distance_to_center * (point2_x - point1_x) / distance_between_points
# Count the number of points inside the circle with center 2.
points_inside_center2 = 0
for k in range(number_of_points):
point_x, point_y = points[k]
distance_to_center2 = math.sqrt((point_x - center2_x)**2 + (point_y - center2_y)**2)
if distance_to_center2 <= radius:
points_inside_center2 += 1
max_points_inside = max(max_points_inside, points_inside_center2)
# Iterate through all points as possible centers
for i in range(number_of_points):
point_x, point_y = points[i]
points_inside = 0
# Check all other points if they fall within radius
for j in range(number_of_points):
other_point_x, other_point_y = points[j]
distance = math.sqrt((point_x - other_point_x)**2 + (point_y - other_point_y)**2)
if distance <= radius:
points_inside += 1
# Update the max points inside the circle
max_points_inside = max(max_points_inside, points_inside)
return max_points_inside| Case | How to Handle |
|---|---|
| Empty points array | Return 0 immediately since no points can be inside the dartboard. |
| All points are the same. | The algorithm should still correctly identify that all these points are inside a circle of radius r centered on that single point. |
| Points are extremely far apart compared to the radius r. | The algorithm should still correctly determine the maximum number of points inside a circle, even if it is a small number. |
| Radius r is 0. | The only points inside the circle will be points that are exactly at the center and the algorithm should handle this edge case correctly. |
| Large number of points (performance) | The algorithm's complexity should be analyzed to ensure it scales reasonably with a large number of points to avoid exceeding time limits. |
| Floating point precision errors when calculating distances. | Use a small tolerance (epsilon) when comparing distances to the radius to account for potential floating-point inaccuracies. |
| Integer overflow when calculating squared distances. | Use appropriate data types (e.g., long long in C++) to avoid integer overflow when calculating squared distances. |
| No valid circle exists containing more than one point | The algorithm should correctly identify and return 1 if no circle contains more than one point, because we can choose one point. |