参考思路:固定一个点,枚举剩下的点所构成直线(斜率)
先固定一个点,然后计算该点到其他所有点的斜率,最后统计得到最多的共线的点的个数。
时间复杂度为O(n^2),需要借助map数据结构保存中间结果,空间复杂度为O(n)。
在处理的过程中要注意:
1.curpoint 不在map之中,但map是curpoint对应的map,如果map之中有两个点,那么共线的点总共有3个
2.在固定点下遍历其他点的过程中,遇到相同的点不应该置于map中,而是视为有多个等效起始点,以samepeoint记录重复的起始点的个数
3.所有垂直于x轴的斜率,以[0,1]代替;所有平行于x轴的斜率,以[1,0]代替;
4。在约分之后考虑到[-1,1]其实与[1,-1]是共线的,所以要固定一端恒为+即可避免二次判断
/**
* Definition for a point.
* struct Point {
* int x;
* int y;
* Point() : x(0), y(0) {}
* Point(int a, int b) : x(a), y(b) {}
* };
*/
class Solution {
public:
int maxPoints(vector<Point>& points) {
int size = points.size();
if(size <= 2)
return size;
int ans = 0;
map<pair<int,int>,int> cal;
for(int i = 0;i < size;++i)
{
// 剪枝,最好case剩余的size - i - 1个点均与当前点共线
if(size - i <= ans)
break;
int maxinmap = 0;
int samepoint = 0;
cal.clear();
for(int j = i + 1;j < size;++j)
{
if(points[j].x == points[i].x)
{
if(points[j].y == points[i].y)
++samepoint;
else
maxinmap = max(maxinmap,++cal[make_pair(0,1)]);
}
else
{
int dy = points[j].y - points[i].y;
int dx = points[j].x - points[i].x;
if(dy != 0)
{
int g = gcd(abs(dx),abs(dy));
dx /= g;
dy /= g;
if(dy < 0)
{
dx = 0 - dx;
dy = 0 - dy;
}
maxinmap = max(maxinmap,++cal[make_pair(dy,dx)]);
}
else
maxinmap = max(maxinmap,++cal[make_pair(1,0)]);
}
}
ans = max(ans,maxinmap + samepoint + 1);
}
return ans;
}
int gcd(int m,int n)
{
if(n == 0)
return m;
if(m < n)
return gcd(n,m);
return gcd(n,m % n);
}
};