Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
刚拿到这个题的时候一看是计算几何,心里就有些发憷,因为在搞ACM的时候,遇到计算几何的题就跳过,从来不敢碰。
但后来又好好想了一下,发觉这只是皮了计算几何的外衣,其实还是一个搜索遍历的题。
思路1,暴力
可以两两连线,判断其他的点有没有在这条线上,并统计在同一条线上点的个数,最后取最大的。这种方法的时间复杂度是十分高的,首先是两两连线,就是O(n2),然后还要判断每个点在不在线上所以最后的时间复杂度是O(n3)。
思路2,通过判断斜率来判断是不是在一条直线上
选定一个点,然后分别和剩下的点求组成直线的斜率,然后用hashmap来存储记录每一个斜率所包含点的个数,通过这种时间置换空间的方法,将时间复杂度缩短到O(n2)
注意:我在做这个题的时候遇到了一个问题导致自己用了很长时间才AC,因为其中遇到了斜率为-0.0和0.0的问题,我发现在Java中的Double类中,是存储的这两个值,而不是把他们看做相等来进行的。
public static int maxPoints(Point[] points) {
int len = points.length;
if(len == 0)return 0;
Map<Double, Integer> map = new HashMap<Double,Integer>();
int MaxNum=1;
for(int i=0;i<len;i++){
map.clear();
int samePointNum=0;
int tempress = 1;
for(int j=i+1;j<len;j++){
//把斜率初始化为最大值
Double slope = Double.MAX_VALUE;
if(points[i].x != points[j].x){
slope = 1.0*(points[i].y - points[j].y)/(1.0*(points[i].x - points[j].x));
}
else if(points[i].y == points[j].y){
samePointNum++;
continue;
}
if(slope.equals(-0.0) ){
slope = 0.0;
}
int temp =0;
if(map.containsKey(slope)){
int value = map.get(slope);
map.put(slope, ++value);
temp = value;
}
else{
map.put(slope, 2);
temp = 2;
}
if(tempress < temp)
tempress = temp;
}
if(MaxNum < tempress + samePointNum)
MaxNum = tempress + samePointNum;
}
return MaxNum;
}