Max Points on a Line(leetcode)

来源:互联网 发布:软件开发技术基础 编辑:程序博客网 时间:2024/05/28 16:02

题目:

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

题目来源:https://oj.leetcode.com/problems/max-points-on-a-line/

解题思路:由两点计算出斜率,然后根据斜率和初始点计算任意一点是否在这两点所确定的直线上,如果在就把计数器+1,返回最多的点的直线上的点数。

注意:如果第一个点是[1,3],第5个点也是[1,3],则在第5个点往后的点,以[1,3]为起点计算时,都需要加两遍[1,3],这个地方要特别注意。但是leetcode题解上避免了这个问题,可以从代码上看出来,如果点M和点N的x轴坐标相等,则只计算和x轴其坐标相等的点,否则利用公式计算。这样就把两个相等的点放到了第一种情况。

#include<iostream>#include<vector>using namespace std;struct Point {    int x;    int y;    Point() : x(0), y(0) {}    Point(int a, int b) : x(a), y(b) {}};int maxPoints(vector<Point> &points){if(points.size()<=1)return points.size();const int N=points.size();int result=0,temp=1;for(int i=0;i<N;i++){temp=1;int firstNum=temp;for(int j=i+1;j<N;j++){if(points[j].x==points[i].x && points[j].y==points[i].y){temp++;//表示到目前为止第一个数即points[i]重复出现的次数,因为每次重复相当于每条线都有加一个点firstNum++;continue;}temp++;double k=(points[j].x-points[i].x)==0?0:double(points[j].y-points[i].y)/(points[j].x-points[i].x);for(int m=j+1;m<N;m++){double tempk=(points[m].x-points[i].x)==0?0:double(points[m].y-points[i].y)/(points[m].x-points[i].x);if(k==tempk || (points[m].x==points[i].x && points[m].y==points[i].y) || (points[m].x==points[j].x && points[m].y==points[j].y))temp++;}if(temp>result)result=temp;temp=firstNum;}if(temp>result)result=temp;}return result;}int maxPoints1(vector<Point> &points){if(points.empty())return 0;const int N=points.size();int temp=0;int result=0;for(int i=0;i<N;i++){temp=1;int firstNum=temp;for(int j=i+1;j<N;j++){int A=points[i].x-points[j].x;int B=points[i].y-points[j].y;if(A==0 && B==0){temp++;firstNum++;continue;}temp++;for(int m=j+1;m<N;m++){if((A==0 && points[m].x==points[i].x) || (points[m].y-points[i].y)*A==B*(points[m].x-points[i].x))temp++;}result=max(result,temp);temp=firstNum;}result=max(result,temp);}return result;}int maxPoints2(vector<Point> &points){if(points.size()<3)return points.size();int result=0;for(int i=0;i<points.size()-1;i++){for(int j=i+1;j<points.size();j++){int sign=0;int a,b,c;if(points[i].x==points[j].x)sign=1;else{a=points[j].x-points[i].x;b=points[j].y-points[i].y;c=a*points[i].y-b*points[i].x;}int count=0;for(int k=0;k<points.size();k++){//这里巧妙的避免了上面所出现的问题及firstNum的问题if((0==sign && a*points[k].y==c+b*points[k].x) || (1==sign && points[k].x==points[j].x))count++;}if(count>result)result=count;}}return result;}int main()  {  freopen("input.txt","r",stdin);vector<Point> points;int x,y;while(cin>>x>>y){points.push_back(Point(x,y));}int result=maxPoints(points);int result1=maxPoints1(points);int result2=maxPoints2(points);    system("pause");      return 0;  }

以上的跌代版的时间复杂度是O(n^3),下面的算法是以每个点为中心,计算构成的每条线的斜率来算的,这样能够使复杂度降低到O(n^2),参考的是《leetcode题解》。

#include<iostream>#include<vector>#include<unordered_map>using namespace std;struct Point {    int x;    int y;    Point() : x(0), y(0) {}    Point(int a, int b) : x(a), y(b) {}};int maxPoints(vector<Point> &points){if(points.size()<3)return points.size();const int N=points.size();int result=0;unordered_map<double,int> slopmap;for(int i=0;i<N;i++){slopmap.clear();int samePoint=0;int commenLineNum=1;for(int j=i+1;j<N;j++){double slop;if(points[i].x==points[j].x && points[i].y==points[j].y){samePoint++;continue;}if(points[i].x==points[j].x)slop=double(INT_MAX);elseslop=double(points[i].y-points[j].y)/(points[i].x-points[j].x);int count=0;if(slopmap.find(slop)!=slopmap.end())count=++slopmap[slop];else{count=2;slopmap[slop]=count;}if(count>commenLineNum)commenLineNum=count;}result=max(result,samePoint+commenLineNum);}return result;}int main()  {  freopen("input.txt","r",stdin);vector<Point> points;int x,y;while(cin>>x>>y){points.push_back(Point(x,y));}int result=maxPoints(points);    system("pause");      return 0;  }


0 0
原创粉丝点击