题目出处:https://leetcode.com/submissions/detail/47640173/
题意描述:
由于过于简洁,故不再翻译,具体描述见一下英文描述:
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
解决思路:
看到这道题,首先肯定就会想到遍历所以起点和终点,并判断起点和终点连成的直线经过了多少个点。在遍历的过程中更新最大值即可。由于这种算法需要遍历三边点集,因此复杂度为O(n^3)。稍微高了点,但是可以先试试,万一可以了呢。于是欢快的写出了下面的代码:
1 class Solution { 2 public: 3 bool inOneLine(Point p1, Point p2, Point p3) 4 { 5 return ((p3.y-p1.y)*(p2.x-p1.x) == (p2.y-p1.y)*(p3.x-p1.x)); 6 } 7 bool equal(Point p1, Point p2) 8 { 9 return (p1.x == p2.x && p1.y == p2.y); 10 } 11 12 int maxPoints(vector<Point>& points) { 13 if(points.size() <= 2) 14 return points.size(); 15 int ans = 2; 16 int n = points.size(); 17 for(int i = 0; i < n; i ++) 18 { 19 for(int j = i+1; j < n; j ++) 20 { 21 int sum = 0; 22 if(equal(points[i], points[j])) 23 { 24 for(int k = 0; k < n; k ++) 25 if(equal(points[i], points[k])) 26 sum ++; 27 } 28 else 29 { 30 for(int k = 0; k < n; k ++) 31 { 32 if(inOneLine(points[i], points[j], points[k])) 33 { 34 sum ++; 35 } 36 } 37 } 38 ans = max(ans, sum); 39 } 40 } 41 return ans; 42 } 43 };
写这段代码还是蛮快的,只是需要注意的是起点和终点可能相同的情况,以及点的数量少于3的情况,把这些情况考虑进去之后,就可以提交了。
最后,这段代码竟然奇迹般的AC了,看样子这道题对复杂对并没有比较高的要求。由于还有两个大作业没有动工,于是就不改进复杂度了,不过可以写写改进的思路。其中一个可以将复杂度优化为O(n^2)的想法是枚举起点和终点,并计算出起点和终点所形成的直线的斜率和截距。然后通过hash表以斜率和截距为键值储存,并记录下来每个斜率和截距出现的数量。最后遍历一遍hash表找出最大数量即为答案。