给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。
提示:
1 <= points.length <= 300
points[i].length == 2
-104 <= xi, yi <= 104
points
中的所有点 互不相同
解析:使用斜率(slope)来确定两点之间的直线,并通过哈希表(dict)来记录每个斜率对应点的数量对于每一个点,我们可以计算它与其他所有点之间的斜率
遍历每个点-->处理斜率-->处理重合点-->更新最大值-->求出结果并返回
代码实现如下
from fractions import Fraction
from collections import defaultdict
def maxPoints(points):
def slope(p1, p2):
# 如果两点重合
if p1 == p2:
return None
# 如果两点在同一垂直线上
if p1[0] == p2[0]:
return float('inf')
# 使用 Fraction 来避免浮点数精度问题
return Fraction(p2[1] - p1[1], p2[0] - p1[0])
if len(points) <= 2:
return len(points)
max_points = 0
for i in range(len(points)):
slopes = defaultdict(int)
same_point_count = 1 # 计算与当前点重合的点的数量
for j in range(i + 1, len(points)):
if points[i] == points[j]:
same_point_count += 1
else:
s = slope(points[i], points[j])
slopes[s] += 1
# 当前点的最大共线点数 = 重合点数 + 最多相同斜率的点数
current_max = same_point_count + (max(slopes.values(), default=0) if slopes else 0)
max_points = max(max_points, current_max)
return max_points
# 示例用法:
print(maxPoints([[1,1],[2,2],[3,3]])) # 输出: 3
print(maxPoints([[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]])) # 输出: 4
1. slope 函数:
用于计算两个点之间的斜率。如果两点重合,返回 None;如果两点在同一垂直线上,返回 float('inf');否则,使用 Fraction 来计算斜率。
2. maxPoints 函数:
遍历每个点 points[i],将其作为起点。
对于每个起点,初始化一个 defaultdict 来记录不同斜率出现的次数,并初始化 same_point_count 来记录与当前点重合的点的数量
遍历其他点 points[j],计算斜率并更新 slopes 和 same_point_count
计算当前点的最大共线点数,并更新全局最大值 max_points。
3. 返回结果:
最终返回全局最大值 max_points。
这种方法的时间复杂度为 On2,因为我们使用了哈希表来存储斜率。
优化建议:
提前终止、减少重复计算、优化斜率计算、优化斜率计算
1. 提前终止:
如果在遍历过程中,当前点的最大共线点数已经达到了 n,则可以直接返回结果,因为不可能有更多点在同一条直线上。
如果在某个点的遍历中,当前的最大共线点数已经超过了之前的所有结果,可以提前终止对该点的进一步处理。
2. 减少重复计算:
使用缓存来存储已经计算过的斜率,避免重复计算。
对于重合点,可以在第一次遇到时直接跳过后续的比较,减少不必要的计算。
3. 优化斜率计算:
使用 Fraction 来避免浮点数精度问题,但也可以考虑使用整数除法来简化斜率的表示。例如,对于斜率 (dy, dx),可以直接使用 (dy, dx) 的最小公倍数来表示斜率,而不需要使用 Fraction。
4. 并行化:
如果硬件支持多线程或分布式计算,可以将点的遍历过程并行化,从而加速计算。不过,这并不会改变时间复杂度,但可以在实际运行中提高效率。