题目要求:
给定2D平面上的n个点,找出位于同一条直线上的最大点数。
解决思路
这个问题的一种方案是考虑两点之间斜率,把斜率相同的点放置在一个表中,再找到包含最多点的斜率。这个其中有两点需要关注,一个是点坐标的取值范围,一个是涉及斜率计算的问题。
我的想法是对于每一个点,分别计算在它之后的所有不同点的斜率,并且用一个Map集合存起来,对于这个点,找出斜率最大的那个。考虑它的正确性,我们可以假设一种极端情况,即给定所有的点都在一条直线上,那么第一个点中肯定已经可以计算所要的结果,其他的点虽然能正常运行,但是同一个斜率得到结果肯定比第一个少。
这里还要指出的是,斜率计算的问题,当横坐标相同时,用Integer.MAX_VALUE表示。考虑到Double运算可能会出现精度溢出情况,采用了BigDecimal类来计算精确结果。
java代码
/**
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
class Solution {
public int maxPoints(Point[] points) {
int res = 1;
if(points.length==0) return 0;
for(int i =0;i<points.length;i++){
HashMap<Double,Integer> hm = new HashMap<>();
hm.put((double) Integer.MIN_VALUE,1);//当points数组不空时,直线上必有一点
int de = 0;
for(int j=i+1;j<points.length;j++){
if((points[i].y==points[j].y)&&(points[i].x==points[j].x)){
de++;
}else{
double tt = dis(points[i],points[j]);
if(hm.containsKey(tt))
hm.put(tt,hm.get(tt)+1);
else
hm.put(tt,2);
}
}
for(int re:hm.values())
res = Math.max(res, de+re);
}
return res;
}
public static double dis(Point p1, Point p2) {
if((p1.x-p2.x)==0)
return (double)Integer.MAX_VALUE;
if(p1.y==p2.y)
return 0;
java.math.BigDecimal bd1 = new java.math.BigDecimal(Double.toString(p1.y-p2.y));
java.math.BigDecimal bd2 = new java.math.BigDecimal(Double.toString(p1.x-p2.x));
return bd1.divide
(bd2,16,java.math.BigDecimal.ROUND_HALF_UP).doubleValue();
}
}