Max Points on a Line
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
哈希表
复杂度
时间 O(N^2) 空间 O(N)
思路
一个点加一个斜率,就可以唯一的确定一条直线。所以我们对每个点,都计算一下该点和其他点连线的斜率,这样对于这个点来说,相同斜率的直线有多少条,就意味着有多少个点在同一条直线上,因为这些直线是相同的。另外,如果计算过点A和点B的直线,当算到点B时,就不用再和A连线了,因为AB这条直线上的点数已经都计算过了。这里,我们用哈希表,以斜率为key,记录有多少重复直线。
注意
哈希表的Key为Double,但Double是可以有正0和负0的,而且不一样。所以我们要用if(slope * slope == 0) slope = 0;
把负0都变成正0
代码
public class Solution {
public int maxPoints(Point[] points) {
if(points.length <= 1) return points.length;
int max = Integer.MIN_VALUE;
for(int i = 0; i < points.length; i++){
//过当前点的直线组成的哈希表,斜率为key
HashMap<Double, Integer> lines = new HashMap<Double, Integer>();
int vertical = 0, same = 1, currMax = 0;
for(int j = i + 1; j < points.length; j++){
// 统计相同的点
if(points[i].x == points[j].x && points[i].y == points[j].y){
same++;
continue;
}
// 统计斜率为无穷的点,他们都在一条直线上
if(points[i].x == points[j].x){
vertical++;
continue;
}
// 计算连线的斜率
double slope = ((double)points[i].y - (double)points[j].y) / ((double)points[i].x - (double)points[j].x);
// 修正负0
if(slope * slope == 0) slope = 0;
lines.put(slope, lines.containsKey(slope) ? lines.get(slope) + 1 : 1);
currMax = Math.max(currMax, lines.get(slope));
}
// 经过该点的直线上最多的点数,我们在无穷斜率和正常斜率中选较大的,还要加上相同的点数
currMax = Math.max(vertical, currMax) + same;
max = Math.max(currMax, max);
}
return max;
}
}