leetcode 149 直线上最多的点
一道让人难以发力,难以下手的题目。看了题解之后觉得思路并不困难。遍历所有点,对某一点而言,计算其到所有另外点的斜率,其中最多的斜率,就是过这一点的点最多的某条直线的斜率。通过这个思路去遍历所有点就能得到结果。而有几个优化的方面,一个是对于每个点,只需要计算该节点与该节点后面的点的斜率,因为如果对于j计算其与i之间的斜率,这一直线已经在对i遍历的时候计算过了,所以不需要重新计算。第二点是斜率的保存方式,该例中使用二元组的方式保存斜率,并且通过计算最大公约数的方式进行约分,若上下分别为0则有特殊的操作,这样以来就能够保证斜率的正确性。第三点,如果当前存储的结果大于n的一半或者大于剩余未遍历的节点,则可以提前返回,因为在这两种情况下,经过剩下的点的直线经过的点都无法比当前结果更多,所以可以提前结束。贴代码
1 class Solution { 2 public: 3 int gcd(int a,int b) 4 { 5 return b?gcd(b,a%b):a; 6 } 7 int maxPoints(vector<vector<int>>& points) 8 { 9 int n = points.size(); 10 if(n<=2) 11 return n; 12 int ret = 0; 13 for(int i = 0 ; i < n ; i++) 14 { 15 if(ret>n-i || ret>n/2) 16 return ret; 17 unordered_map<int,int> mp; 18 for(int j = i+1 ; j < n ; j++) 19 { 20 int x = points[i][0]-points[j][0]; 21 int y = points[i][1]-points[j][1]; 22 if(x == 0) 23 y = 1; 24 else if(y == 0) 25 x = 1; 26 else 27 { 28 if(y<0) 29 { 30 x = -1*x; 31 y = -1*y; 32 } 33 int gcdXY = gcd(abs(x),abs(y)); 34 x/=gcdXY; 35 y/=gcdXY; 36 } 37 mp[y+x*20001]++; 38 } 39 int maxn = 0; 40 for(auto& [_,num]:mp) 41 maxn = max(maxn,num+1); 42 ret = max(ret,maxn); 43 } 44 return ret; 45 } 46 };

浙公网安备 33010602011771号