Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
思路:输入的点可能有重复。两个不同的点确定一条直线,简单想法是做个二重循环,计算每一对点所确定的直线,将直线的信息保存起来,最后合并相同的直线,得到点的个数。直线的唯一性由斜率slope和截距两个值确定,斜率相等的两条直线可能是平行线,不是同一条直线。斜率的计算方法是:
slope=(A.Y-B.Y)/(A.X-B.X)
且注意,分母不能为0,分母为零时,说明两个点的直线是 X=a;
上面的暴力法显然不合适,我们可以这样思考,对于某个点i,求出其他所有点与它所确定的直线,因为这些直线都包含点 i ,所以只要斜率相等,那么就一定是同一条直线,我们用 map<double, int> 来保存每个斜率slope 对应的点个数。这样外层循环遍历每一个点计算map值,内层循环只考虑点 i 后面的点,以避免重复计算,用一个中间变量保存当前的某条直线上最多的点个数。每次外层循环都将map清空,这样节省空间。
/**
* 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) {
unordered_map<double, int> umap;
int res=0;
int len=points.size();
if(len>0){
for(int i=0; i<len; ++i){
int samepoints=0;
umap.clear();
int tempres=1;
for(int j=i+1; j<len; ++j){
double slope=numeric_limits<double>::infinity();
int dx=points[i].x-points[j].x;
int dy=points[i].y-points[j].y;
if(dx==0){
if(dy==0){
samepoints++;
if(res<samepoints)
res=samepoints;
continue;
}
}
else{
slope=1.0*dy/dx;
}
if(umap.find(slope)!=umap.end()){
umap[slope]++;
}
else{
umap.insert(unordered_map<double, int>::value_type(slope, 2));
}
if(tempres<umap[slope])
tempres=umap[slope];
}
if(res<tempres+samepoints)
res=tempres+samepoints;
}
}
return res;
}
};