- 题目并不复杂,但是要考虑到的情况也是不少。需要注意一条线上有多个点的情况。
第一种方法
非常容易想到的是暴力枚举,即对于一个点而言,所有与它在同一条线上的点必定会有相同的斜率,所以只要记下相同斜率时的最大点数即可。这里有一个问题时如果所枚举点重复出现的时候比较麻烦,需要用另外一个变量记录下来。
#include <iostream>
#include <vector>
#include <map>
using namespace std;
struct Point {
int x;
int y;
Point() : x(0), y(0) {}
Point(int a, int b) : x(a), y(b) {}
};
#define INF (1<<31)
class Solution {
public:
int maxPoints(vector<Point>& points) {
if(points.size()<=1)
{
return points.size();
}
int maximum = 1;
for(unsigned int i = 0 ; i < points.size() ; i++ )
{
map<long double,int> m;
m.clear();
int same = 0;
for(unsigned int j = 0 ; j < points.size() ; j++)
{
if(i==j)
continue;
long double k;
if(points[i].x==points[j].x)
{
if(points[i].y==points[j].y)
{
same++;
continue;
}
else
{
k = INF;
}
}
else
{
k = (long double)(points[i].y-points[j].y)/(points[i].x-points[j].x);
}
if(m.find(k)==m.end())
{
m[k] = 2;
}
else
{
m[k]++;
}
if(m[k]+same>maximum)
{
maximum = m[k]+same;
}
}
if(maximum == 1)//这种情况只发生在整条直线只有一种点的情况
{
maximum = same + 1;
}
}
return maximum;
}
};
/*
题目大意:给出一串点,找到能用一条线串起的点的最大数值。
两个点之间必定确定一条直线
三个点共线,当且仅当第一个点到第二点的斜率等于第二个点到第三个点的斜率
比较暴力的想法:不断去枚举,第一个点从第二点到第n点,每个点确定斜率,如果斜率相同,确定是否能在同一条线上。
O(n^2)的想法
使用map来优化,想法:从一个点出发的斜率相同的点必定在同一个直线上,或者为同一点。
需要考虑到的情况:1.点在同一个的问题。2.没有点的问题。3.斜率超过浮点界限的问题
*/
int main(void)
{
Solution s;
vector<Point> points;
points.push_back(Point(0,0));
points.push_back(Point{94911151,94911150});
points.push_back(Point{94911152,94911151});
cout<<s.maxPoints(points)<<endl;
return 0;
}
值得一提的是对于这个数据,如果使用另外一个结构体(x,y)作为map的键,只要存在第二个结构体都不给过,个人感觉是leetcode编译设置问题,稍微有点坑。