-
[题目链接](149. 直线上最多的点数 - 力扣(LeetCode))
-
解题思路:两个for循环。某一条直线,必须经过第一个点,最多经过多少点?某一条直线,必须经过第二个点,最多经过多少个点?以此类推,最多的那个结果,就是答案。
- 怎么知道必须经过某个点的【直线】,最多经过多少点?例如现在必须经过的点是
(x, y)
,我们只需要计算这个点和其他点的斜率即可。斜率还有一个问题,两个点,横坐标相同时,怎么办?纵坐标相同时,又怎么办?看代码具体处理。 - 还有一个细节,当处理j个点时,不必再看
[0, j - 1]
的点了,为什么?假设最优解是同时经过j与i(i < j
)的直线,我们在计算i的点时,已经计算过,【同时经过i和j】的直线了。
- 怎么知道必须经过某个点的【直线】,最多经过多少点?例如现在必须经过的点是
-
代码
class Solution:class twoPointRelation():def __init__(self, x, y, same):self.x = x # 斜率的分母self.y = y # 斜率的分子self.same = same # 为True,代表分母或者分子为0 分母为0时:x为0,y就是两个点的x轴的值, 分子为0时:y为0,x就是两个点y轴的值# 下面这两个函数是为了在字典的keydef __hash__(self):return hash((self.x, self.y, self.same))def __eq__(self, other):return self.same == other.same and self.x == other.x and self.y == other.ydef gcd(self, a, b):if b == 0:return areturn self.gcd(b, a % b)def maxPoints(self, points: List[List[int]]) -> int:# 两个点的关系:斜率k,(y1 - y2) / (x1 - x2) 当x相同时 没有斜率dict = {}count = len(points)ans = 0for i in range(count):dict.clear()for j in range(i + 1, count):x1 = points[i][0]y1 = points[i][1]x2 = points[j][0]y2 = points[j][1]first = y2 - y1 # 分子second = x2 - x1 # 分母if second == 0: # 分母为0k = self.twoPointRelation(0, x2, True)elif first == 0: # 分子为0k = self.twoPointRelation(y1, 0, True)else:num = self.gcd(first, second)k = self.twoPointRelation(second / num, first / num, False)if k in dict:dict[k] += 1else :dict[k] = 1ans = max(ans, dict[k])return ans + 1