题目是LeetCode第189场周赛的第三题,链接:1453. 圆形靶内的最大飞镖数量。具体描述见原题。
题目的做法就是枚举两个点的组合,计算以这两个点为圆弧上两点时的圆心位置,然后根据这个圆心位置再遍历一遍所有点,计算处于圆内的点数,至于怎么计算圆心位置那就是几何问题了,具体可以看这里。时间复杂度为 O ( n 3 ) O(n^{3}) O(n3),空间复杂度为 O ( 1 ) O(1) O(1)。
JAVA版代码如下:
class Solution {
public int numPoints(int[][] points, int r) {
int N = points.length;
int result = 1, count;
int r2 = r * r;
double d, h, x, y, center_x, center_y;
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (i == j) {
continue;
}
d = Math.sqrt((points[i][0] - points[j][0]) * (points[i][0] - points[j][0]) + (points[i][1] - points[j][1]) * (points[i][1] - points[j][1])) / 2;
if (d * d > r2) {
continue;
}
h = Math.sqrt(r2 - d * d);
x = (points[i][0] + points[j][0]) / 2.0;
y = (points[i][1] + points[j][1]) / 2.0;
center_x = x - h * (y - points[i][1]) / d;
center_y = y + h * (x - points[i][0]) / d;
count = 0;
for (int[] point : points) {
if ((point[0] - center_x) * (point[0] - center_x) + (point[1] - center_y) * (point[1] - center_y) <= r2 + 1e-7) {
++count;
}
}
result = Math.max(result, count);
}
}
return result;
}
}
提交结果如下:
Python版代码如下:
class Solution:
def numPoints(self, points: List[List[int]], r: int) -> int:
N = len(points)
result = 1
for i in range(N):
for j in range(N):
if i == j:
continue
d = math.sqrt(((points[i][0] - points[j][0])**2 + (points[i][1] - points[j][1])**2)) / 2
if d > r:
continue
x = (points[i][0] + points[j][0]) / 2
y = (points[i][1] + points[j][1]) / 2
h = math.sqrt(r**2 - d**2)
center_x = x - h * (y - points[i][1]) / d
center_y = y + h * (x - points[i][0]) / d
count = 0
for point in points:
if (point[0] - center_x)**2 + (point[1] - center_y)**2 <= r**2 + 1e-7:
count += 1
result = max(result, count)
return result
提交结果如下: