给定一些二维平面上的点,问最多有几点共线。
乍一看并不难,直接计算两两之间的斜率,然后遍历每个点,看其它点与之连线的斜率最多有几个相同的,更新答案,遍历后即得到最终答案。
思路不难,但是这道题有几个坑需要注意:
- 竖直直线的斜率如何处理
- 非整数的斜率要用double类型吗?最后精度取多少合适呢?
以上两个问题其实可以用一种方法解决,那就是用既约分数来表示,这样竖直直线的斜率为1/0,非竖直直线的斜率为p/q的有理数形式。
这道题还有一个坑点在于数据可能包含重复点,所以要增设一个变量repeat来记录重复点,这是我在WA了一次后发现的。
搞定了以上的坑,这题就没什么难点了:
class Solution
{
public:
int gcd(int a, int b)
{
while (b)
{
a = a % b;
swap(a, b);
}
return a;
}
int maxPoints(vector<vector<int>>& points)
{
int n=points.size();
if(n==0||n==1||n==2) return n;
long slope[n][n];
map<string,int> cnt;
int ans=1,repeat=0;
for(int i=0;i<n;i++)
{
cnt.clear();
repeat=0;
for(int j=i+1;j<n;j++)
{
if(points[i][0]==points[j][0]&&points[i][1]==points[j][1])
repeat++;
else
{
long dy=(long)points[i][1]-(long)points[j][1];
long dx=(long)points[i][0]-(long)points[j][0];
long GCD=gcd(dy,dx);
dy/=GCD;
dx/=GCD;
cnt[to_string(dy)+'_'+to_string(dx)]++;
}
}
if(!cnt.empty())
for(auto iter=cnt.begin();iter!=cnt.end();iter++)
ans=max(ans,repeat+iter->second);
else
ans=max(ans,repeat);
}
return ans+1;
}
};