Skip to main content

149.同一直线上的最多点数

标签: hash-table, math, array

难度: Hard

通过率: 28.0%

原题链接: https://leetcode.com/problems/max-points-on-a-line/description/

题目描述

给定一个点数组,其中points[i] = [xi, yi]表示X-Y平面上的一个点,返回相同直线上最多的点数。

解题思路

要解决这个问题,主要是找到最大数量的共线点。对每个点i,我们需要计算通过它与其他任何一个点j (j != i) 的直线,并记录这些直线。这里的关键是在计算斜率时需要处理浮点数精度问题。为避免浮点误差,我们使用分数形式表示斜率,即 (dy/dx),其中 dy 和 dx 是两点间的y差和x差。同时为处理负斜率的方向,常通过求最大公约数(GCD)来标准化分数。`

具体步骤如下:

  1. 使用双重循环,外循环选择每个点作为起点i。内循环与其他点j (j != i) 计算斜率。
  2. 使用哈希表记录每条通过点i的直线上点的个数,key为斜率。
  3. 对每个起点i,找到具有相同斜率的直线上最多的点。
  4. 更新答案为所有情况下直线上最大点数。

注意,直接重合的点应特殊处理,每遇到一个直接重合的点,应额外在当前经过该点的直线基础上加1。

代码实现

from collections import defaultdict`
`import math`
``
def maxPoints(points):`
def gcd(a, b):`
while b:`
a, b = b, a % b`
return a`
``
def slope(p1, p2):`
dx = p2[0] - p1[0]`
dy = p2[1] - p1[1]`
if dx == 0:`
return ('inf', 0) # 垂直线的特殊标记`
g = gcd(dx, dy)`
return (dy // g, dx // g)`
``
n = len(points)`
if n < 3:`
return n`
max_points = 0`
``
for i in range(n):`
slopes = defaultdict(int)`
duplicates = 1`
for j in range(i + 1, n):`
if points[i] == points[j]:`
duplicates += 1`
else:`
s = slope(points[i], points[j])`
slopes[s] += 1`
``
max_points = max(max_points, max(slopes.values(), default=0) + duplicates)`
``
return max_points

复杂度分析

时间复杂度为 O(n2)O(n^2),因为我们需要对每个点计算通过其他点的斜率。

空间复杂度为 O(n)O(n),用于存储每个点的斜率信息和重合点数。