描述
给出二维平面上的n个点,求最多有多少点在同一条直线上。
您在真实的面试中是否遇到过这个题? 是
题目纠错
样例
给出4个点:(1, 2)
, (3, 6)
, (0, 0)
, (1, 3)
。
一条直线上的点最多有3个。
题意很简单,思路就是二重循环枚举一下
计算i点和j点的斜率K_ij,然后记录K_ij出现的次数,取最大的那个就是直线过i点的最大共线点个数。枚举完所有的i取最大就可以了
然后这个题需要注意一下细节。。
网上很多解法其实相当不严密,我看到好多人都是用一个double来记录斜率K,然后记录这个K出现的次数。这其实是非常不严密的,计算机当中如果用double就要考虑到精度损失的问题,所以这里不能用double,而应该计算最大公约数然后约分,保存分子分母来记录斜率
然后还有个坑是题目的点有重复点,这里需要过滤一下重复点,然后记录每个重复点重复了多少次。具体可以看我代码
class Solution{
public:
int gcd(int a,int b)
{
if(b==0)
return a;
else
return gcd(b,a%b);
}
int maxPoints(vector<Point> &points)
{
int i,j,result=0;
vector<Point> distinct_points;
map<pair<int,int>,int> points_num;
for(auto iter=points.begin();iter!=points.end();++iter)
{
pair<int,int> pt=make_pair(iter->x,iter->y);
if(points_num[pt])
++points_num[pt];
else
{
distinct_points.push_back(Point(iter->x,iter->y));
++points_num[pt];
}
}
for(i=0;i<distinct_points.size();++i)
{
map<pair<int,int>,int> k_record;
int base_num=points_num[make_pair(distinct_points[i].x,distinct_points[i].y)];
int temp_result=0;
for(j=i+1;j<distinct_points.size();++j)
{
int dx=distinct_points[i].x-distinct_points[j].x;
int dy=distinct_points[i].y-distinct_points[j].y;
int g=gcd(abs(dx),abs(dy));
pair<int,int> k;
if(dy<0)
k=make_pair(-dy/g,-dx/g);
else
k=make_pair(dy/g,dx/g);
int new_num=k_record[k]+points_num[make_pair(distinct_points[j].x,distinct_points[j].y)];
temp_result=max(temp_result,new_num);
k_record[k]=new_num;
}
result=max(result,temp_result+base_num);
}
return result;
}
};