题目描述
给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
示例 1:
1 | 输入: [[1,1],[2,2],[3,3]] |
示例 2:
1 | 输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] |
分析
如何判断一个点在某条直线上?
我们知道一条直线可以用$y=kx+b$来表示,如果点$(x,y)$满足上式则表明$(x,y)$在直线$y=kx+b$上。
这样的话,对于points
中的每个点,可以分别计算其和其它每个点形成的直线,而这些直线重复数量的最大值就是经过该点的直线所能经过的最大点数。
举个例子:
points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
,对于$a=(1, 1)$来说,它和$b=(3, 2)$形成的直线为
$$y = \frac{1}{2}x+\frac{1}{2}$$其中
$$k=\frac{a[0]-b[0]}{a[1]-b[1]}$$
$$b = b[1]-k*b[0]$$
同理,$a=(1, 1)$和剩余的点形成的直线分别为$y = \frac{1}{2}x+\frac{1}{2}$,$y = 1$,$y = 2x-1$和$x = 1$。
观察上述直线的$k$,可以发现其中有两个值为$1/2$,一个值为$2$,还有$inf$和$0$各一个。
我们可以用$k$作为键值的hashmap来记录这些数据出现的次数,这样就能在$O(1)$的时间内完成更新的操作,因为需要更新N个点,所以总体时间复杂度为$O(N)$。
最后在hashmap中取最大的值加一就是就是经过该点的直线所能经过的最大点数。
对于数组中的每个点进行上述操作取结果最大值就是题目所要求的数,最终时间复杂度为$O(N^2)$。
注意:
测试用例中存在重复点的情况,比如
[[0,0],[0,0]]
,代码中需要判断两点坐标是否相同,如果相同那么结果直接+1就不需要更新hashmap了。两点可能在一条竖线上,这样就无法计算出$k$,因为$a[1]-b[1]=0$,数不能被0除,要特殊处理。
代码
1 | from collections import * |
—s
执行用时 :104 ms, 在所有 Python3 提交中击败了66.67%的用户
内存消耗 :13 MB, 在所有 Python3 提交中击败了100.00%的用户