【Leetcode】149. Max Points on a Line 149. 直线上最多的点数
程序员文章站
2022-07-15 12:43:15
...
解法
太多坑了这题
只能依次记录每条直线上的点
需要解决的问题就是:
如何唯一地标识一条直线?
用三元组(A,B,C)
,要注意2点,一是最简约分,二是统一正负号。比如我就统一为第一个非0的数为正
另外还有一个坑:
如何处理重复点?
首先,重复点不能作为得到直线的两个端点
其次,重复点的重复次数也是答案的候选者之一
# Definition for a point.
# class Point(object):
# def __init__(self, a=0, b=0):
# self.x = a
# self.y = b
class Solution(object):
def maxPoints(self, points):
"""
:type points: List[Point]
:rtype: int
"""
def simplify(a,b,c):
# print 'before:',a,b,c
d = 2
m = min(map(abs,filter(lambda x:x,(a,b,c))) or [-1])
if m==-1:
return a,b,c
while d*d<=m:
if m%d==0:
while a%d==0 and b%d==0 and c%d==0:
a,b,c = a/d,b/d,c/d
m /= d
while m%d==0:
m/=d
d += 1
if m>1:
while a%m==0 and b%m==0 and c%m==0:
a,b,c = a/m,b/m,c/m
# print 'after',a,b,c
return a,b,c
def ABC(a,b):
x = b[0]-a[0]
y = b[1]-a[1]
i,j,k = y,-x,a[1]*x-y*a[0]
if i<0 or (i==0 and j<0) or (i==0 and j==0 and k<0):
i,j,k = -i,-j,-k
return i,j,k
from collections import defaultdict
cnt = defaultdict(set)
for i,p in enumerate(points):
cnt[(p.x,p.y)].add(i)
n = len(cnt)
if n<=2:
return len(points)
ans = defaultdict(set)
for i,j in itertools.combinations(cnt.keys(),2):
line = simplify(*ABC(i,j))
ans[line] |= cnt[i] | cnt[j]
return max(map(len,ans.values()+cnt.values()))