题目描述:
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
题目分析:
这道题就是给你一个2D平面,然后给你的数据结构是由横纵坐标表示的点,然后看哪条直线上的点最多。
(1)两点确定一条直线
(2)斜率相同的点落在一条直线上
(3)坐标相同的两个不同的点算作2个点(谨记避免重复)
1 暴力求解:对于每两个点,求出与这两个点在同一直线的所有点,比较简单粗暴。
public class MaxPoints {
/*public class Point {
int x;
int y;
Point() { x = 0; y = 0; }
Point(int a, int b) { x = a; y = b; }
}
*/
public static int maxPoints(Point[] points) {
if(points==null||points.length<=0)
return 0;
if(points.length<=2)
return points.length;
int max=0;
for(int i=0;i<points.length-1;i++){
for(int j=i+1;j<points.length;j++){
int count=2;//至少有两个在同一条直线上
float k=0;
if(points[i].x==points[j].x){
k=Float.MAX_VALUE;
}
else{
//求斜率公式
int bigX=i;
int smallX=j;
if(points[i].x<points[j].x){
bigX=j;
smallX=i;
}
k=(float) (1.0*(points[bigX].y-points[smallX].y)/(points[bigX].x-points[smallX].x));
}
//这里从i而不是从就j的下一位开始,就是为了避免有重复项,比如(1,1)、(1,1)、(1,2)
for(int next=i+1;next<points.length;next++){
if(next==j)
continue;
float k2;
if(points[next].x==points[j].x){
k2=Float.MAX_VALUE;
}
else{
int bigX=next;
int smallX=j;
if(points[next].x<points[j].x){
bigX=j;
smallX=next;
}
k2=(float) (1.0*(points[bigX].y-points[smallX].y)/(points[bigX].x-points[smallX].x));
}
if(k2==k)
count++;
if(k2!=k&&points[next].x==points[j].x&&points[next].y==points[j].y)
count++;
}
if(count>max){
max=count;
//System.out.println(k);
}
}
}
return max;
}
此算法复杂度为O(n^3),比较原始,另参考别人实现的算法,用空间换时间,使用HashMap记录斜率,实现了
O(n^2)算法的
public int maxPoints(Point[] points) {
if(points.length == 0||points == null)
return 0;
if(points.length <= 2)
return points.length;
int max = 1; //the final max value, at least one
for(int i = 0; i < points.length; i++) {
HashMap<Float, Integer> hm = new HashMap<Float, Integer>();
int same = 0;
int localmax = 1; //the max value of current slope, at least one
for(int j = 0; j < points.length; j++) {
if(i == j)
continue;
if(points[i].x == points[j].x && points[i].y == points[j].y){
same++;
continue;
}
float slope = ((float)(points[i].y - points[j].y))/(points[i].x - points[j].x);
if(hm.containsKey(slope))
hm.put(slope, hm.get(slope) + 1);
else
hm.put(slope, 2); //two points form a line
}
for (Integer value : hm.values())
localmax = Math.max(localmax, value);
localmax += same;
max = Math.max(max, localmax);
}
return max;
}