题目
给出二维平面上的n个点,求最多有多少点在同一条直线上。
样例
给出4个点:(1, 2), (3, 6), (0, 0), (1, 3)。
一条直线上的点最多有3个。
解决思路
- 重复的点没有必要去增加时间复杂度, 先把point点简化成没有重复的新数组norepeatvalues以及记录每个新数组的成员point对应的重复次数repeatcounts数组;
- 两个点可以确定一条直线,假设有一个起始点Point[i]和Point[j],它们俩相连的斜率为k,其它只要和它们相连的点必定与它们在同一条直线上;当然,斜率不存在的极端情况也是要考虑在内的,斜率不存在的点,它们点X坐标必定一样;
- 假设(1,3),(2,6),(3,9);有三个(1,3)的重复点,则norepeatvalues成员为[(1,3),(2,6),(3,9)],对应的点重复的个数数组为[2,0,0],在一条直线上的点共有3+2+0+0=5个;
- 由于norepeatvalues的长度和对应的点重复的个数数组repeatcounts长度不定,所以采用ArrayList数组;
核心算法
public class Solution {
public int maxPoints(Point[] points) {
if(points==null){
return 0;
}
int maxcount=0;
int len=points.length;
if(len<2){
return len;
}
ArrayList<Point>norepeatvalues=new ArrayList<Point>();
ArrayList<Integer>repeatcounts=new ArrayList<Integer>();
for(int i=0;i<len;i++){
int repeatcount=0;
boolean isrepeatnum=false;
for(int m=0;m<norepeatvalues.size();m++){
if(norepeatvalues.get(m).x==points[i].x&&points[i].y==norepeatvalues.get(m).y){
isrepeatnum=true;
break;
}
}
if(!isrepeatnum){
for(int j=i+1;j<len;j++){
if(points[i].x==points[j].x&&points[i].y==points[j].y){
repeatcount++;
}
}
norepeatvalues.add(points[i]);
repeatcounts.add(repeatcount);
}
}
len=norepeatvalues.size();
if(len==1){
return len+repeatcounts.get(0);
}
for(int i=0;i<len-1;i++){
for(int j=i+1;j<len;j++){
int tempcount=2+repeatcounts.get(i)+repeatcounts.get(j);
float k=0f;
boolean hasK=true;
if(norepeatvalues.get(i).x==norepeatvalues.get(j).x){
hasK=false;
}else{
k=(float)(norepeatvalues.get(i).y-norepeatvalues.get(j).y)/(norepeatvalues.get(i).x-norepeatvalues.get(j).x);
}
float b=norepeatvalues.get(i).y-k*norepeatvalues.get(i).x;
for(int m=j+1;m<len;m++){
if(hasK){
float curk=(float)(norepeatvalues.get(i).y-norepeatvalues.get(m).y)/(norepeatvalues.get(i).x-norepeatvalues.get(m).x);
if(curk==k){
tempcount=tempcount+repeatcounts.get(m)+1;
}
}else{
if(norepeatvalues.get(i).x==norepeatvalues.get(m).x){
tempcount=tempcount+repeatcounts.get(m)+1;
}
}
}
if(tempcount>maxcount){
maxcount=tempcount;
}
}
}
return maxcount;
}
}