该题解采用了通过每一对点计算斜率的方法来确定穿过最多点的直线。首先,对于每个点 i,使用一个哈希表 d 来记录以该点为起点,其他点与之构成的直线的斜率和对应的点的索引列表。遍历每个点 j (j > i),根据两点确定的斜率将 j 索引加入到哈希表的对应斜率键下。特别地,当两点 x 坐标相同时,斜率为无穷大,使用 inf 表示。之后,检查对于当前点 i,哪个斜率对应的列表最长,即这些点都在同一条直线上。如果这个数量超过了之前记录的最大数量 mx,则更新最大数量和记录直线经过的点的最小两个索引。最终返回穿过最多点的直线的最小两个点的索引。
时间复杂度: O(n^2)
空间复杂度: O(n)
class Solution:
def bestLine(self, points: List[List[int]]) -> List[int]:
ans = [] # 用于存储结果的两个点的索引
mx = 0 # 记录当前发现的最大共线点数
for i, (x, y) in enumerate(points):
d = defaultdict(list) # 字典,键为斜率,值为通过点i和具有该斜率的其他点的索引列表
for j in range(i + 1, len(points)):
xx, yy = points[j]
if x == xx: # x坐标相同,斜率为无穷大
d[inf].append(j)
else: # 计算斜率并存储
d[(yy - y) / (xx - x)].append(j)
l = max(d.values(), key=len, default=[]) # 找到包含点最多的斜率对应的列表
if len(l) > mx: # 如果这个列表的长度大于当前记录的最大长度
mx = len(l) # 更新最大长度
ans = [i, l[0]] # 更新结果
return ans