下面的代码没有精炼过,就写的比较罗嗦了。
平面上任意N点,其中一条直线最多过几个点,这个题显然有O(n^2)的解法,关键的一点是一定要注意cornercase,比较多,我试了7,8次才过….首先考虑相同的点,这个要单独列出来,其次考虑不能用double表示斜率,用一个pair表示分数既可,所以要写gcd来化简,然后注意这里面有负数,所以进行构造的时候要定序,(1,-1),(-1,1)都要变成(-1,1),这样就不会少算了。最后是要注意单独考虑斜率为无穷的点,我这里单独考虑了斜率为0或者为无穷,写的比较罗嗦。最后注意线上的点的个数要加1,因为上面都是统计点的个数!
class Solution {
public:
int maxPoints(vector<Point> &points) {
int n = points.size();
int ret = 0;
for(int i = 0;i<= n-ret;++i){
map<pair<int,int>,int> count;
int maxnum = 0;
int same = 0,vertical = 0,horizon = 0;
for(int j = i+1;j < n;++j){
if(points[i].x==points[j].x && points[i].y==points[j].y){
same+=1;
continue;
}
if(points[i].x==points[j].x){
vertical++;
continue;
}
else if (points[i].y == points[j].y){
horizon++;
continue;
}
auto k = line(points[i],points[j]);
if(count.find(k)==count.end())
count[k] = 0;
count[k] += 1;
if(count[k] > maxnum)
maxnum = count[k];
}
if(maxnum+same>ret)
ret = maxnum+same;
if(max(vertical,horizon)+same > ret)
ret = max(vertical,horizon)+same;
}
return n==0?0:ret+1;
}
pair<int,int> line(const Point& p1,const Point& p2){
int dx = p1.x - p2.x;
int dy = p1.y - p2.y;
int g =gcd(dx,dy);
dx/=g;
dy/=g;
return pair<int,int>(min(dx,dy),max(dx,dy));
}
int gcd(int a,int b){
if(a<b)
return gcd(b,a);
while(a%b){
int t = a%b;
a = b;
b = t;
}
return b;
}
};