1.题目描述
给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
示例 1:
输入: [[1,1],[2,2],[3,3]]
输出: 3
解释:
^
|
| o
| o
| o
+------------->
0 1 2 3 4
示例 2:输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出: 4
解释:
^
|
| o
| o o
| o
| o o
+------------------->
0 1 2 3 4 5 6
2.解题思路
如果几个点共线,那么任意两点的成线的斜率相等。由于两个点 (x1, y1) 和 (x2, y2) 的斜率k表示为 (y2 - y1) / (x2 - x1),通过斜率来判断共线需要用到除法,而用 double 表示的双精度小数在有的系统里不一定准确,为了更加精确无误的计算共线,我们应当避免除法。我们把除数和被除数都保存下来,让这两数分别除以它们的最大公约数,这样例如(8,4)(这里y2 - y1=8,x2 - x1=4)除以最大最大公约数4之后为(2,1);(4,2)除以最大最大公约数2之后为(2,1);(2,1)除以最大最大公约数1之后为(2,1)。这三组商相同的数就都会存到一个映射里面,代表三个斜率一样。
3.代码实现
class Solution(object):
def gcd(self,a,b):
if b==0:
return a
return self.gcd(b,a%b)
def maxPoints(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
size=len(points)
res=0
# 固定一个点i
for i in range(size):
dic={}
x1, y1=points[i][0],points[i][1]
# 这个点自己
duplicate=1
# 遍历i后面的点j
for j in range(i+1, size):
x2,y2=points[j][0],points[j][1]
if x2==x1 and y1==y2:
# 与这个点重合的点的个数
duplicate+=1
else:
dx = x2-x1
dy = y2-y1
d=self.gcd(dx, dy)
dic[(dx//d,dy//d)]=dic.get((dx//d,dy//d),0)+1
# 输入只有一个点,例如[[0,0]]
res=max(res,duplicate)
# 统计固定一个点i后的结果,并更新
for tup, num in dic.iteritems():
res=max(res,num+duplicate)
return res