Leetcode 149. Max Points on a Line
2017-05-27 16:31
489 查看
题目大意
给定二维坐标下的n个点,求其中共线的点的最大个数。
思路分析
两个不同的点可以确定一条直线,设这两个点的坐标分别为(x1,y1)和(x2,y2),则这条直线的方程式可以写成:(x-x1)(y1-y2)=(y-y1)(x1-x2),化简后可以得到:(y1-y2)x+(x2-x1)y=x2y1-x1y2。设a=y1-y2, b=x2-x1, c=x2y1-x1y2,则a、b、c三个数可以确定一条直线(因两个点不同,a和b不可能同时为0)。
题目中要求共线的点的最大个数,两个点必定共线,那么三个不同的点如何判断共线呢?假设这三个不同的点分别是A(x1,y1), B(x2,y2), C(x3, y3),我们可以先求出A和B确定的直线中a、b、c的值,记为(a1,b1,c1),再计算A和C确定的直线中a、b、c的值,记为(a2,b2,c2)。问题转换成如何根据(a1,b1,c1)和(a2,b2,c2)来确定A、B、C三点是否共线。
我们有以下结论,如果存在一个数g使得,a1*g=a2, b1*g=b2, c1*g=c2成立,则A、B、C三点共线。将(a1,b1,c1)进行如下转换:
如果a1,b1,c1均不为0,寻找三个数的绝对值的最大公约数g1,然后进行如下操作:a1/=g1,b1/=g1,c1/=g1。转第四步。
如果a1,b1,c1中只有一个数为0,则对剩下两个数进行第一步中的操作,并转到第四步。
如果a1,b1,c1中只有一个数不为0,则将该数赋值为1。转第四步。
如果a1<0 或者a1==0&&b1<0,则将三个数取值为其相反数。
经过以上步骤,我们得到一条直线的最简表达式,若要对比两条直线是否相同,只需要对比最简化的(a,b,c)即可。
代码实现
定义表示一条直线的结构体:
求两个数的最小正公约数
求直线的最简表达式
求最大共线点数目
总结
在以上处理过程中,需单独考虑某个点重复出现的情况,这时候应该单独计算这些点的数目(同一个点一定共线)。也可以先将这些点的个数统计出来,记录到临时计数器中,当这些点出现在某条直线时,直接从计数器中取出其个数进行叠加等操作。
给定二维坐标下的n个点,求其中共线的点的最大个数。
思路分析
两个不同的点可以确定一条直线,设这两个点的坐标分别为(x1,y1)和(x2,y2),则这条直线的方程式可以写成:(x-x1)(y1-y2)=(y-y1)(x1-x2),化简后可以得到:(y1-y2)x+(x2-x1)y=x2y1-x1y2。设a=y1-y2, b=x2-x1, c=x2y1-x1y2,则a、b、c三个数可以确定一条直线(因两个点不同,a和b不可能同时为0)。
题目中要求共线的点的最大个数,两个点必定共线,那么三个不同的点如何判断共线呢?假设这三个不同的点分别是A(x1,y1), B(x2,y2), C(x3, y3),我们可以先求出A和B确定的直线中a、b、c的值,记为(a1,b1,c1),再计算A和C确定的直线中a、b、c的值,记为(a2,b2,c2)。问题转换成如何根据(a1,b1,c1)和(a2,b2,c2)来确定A、B、C三点是否共线。
我们有以下结论,如果存在一个数g使得,a1*g=a2, b1*g=b2, c1*g=c2成立,则A、B、C三点共线。将(a1,b1,c1)进行如下转换:
如果a1,b1,c1均不为0,寻找三个数的绝对值的最大公约数g1,然后进行如下操作:a1/=g1,b1/=g1,c1/=g1。转第四步。
如果a1,b1,c1中只有一个数为0,则对剩下两个数进行第一步中的操作,并转到第四步。
如果a1,b1,c1中只有一个数不为0,则将该数赋值为1。转第四步。
如果a1<0 或者a1==0&&b1<0,则将三个数取值为其相反数。
经过以上步骤,我们得到一条直线的最简表达式,若要对比两条直线是否相同,只需要对比最简化的(a,b,c)即可。
代码实现
定义表示一条直线的结构体:
typedef struct Line{ long a; long b; long c; Line():a(0),b(0),c(0){} Line(long x, long y, long z):a(x), b(y), c(z){} }Line;
求两个数的最小正公约数
int gcd(long a, long b) { a = abs(a); b=abs(b); if(a<b) swap(a,b); while(b!=0){ long tmp = a%b; a = b; b = tmp; } return a; }
求直线的最简表达式
void simplify(Line &line){ if(line.a==0){ if(line.b==0){ if(line.c!=0) line.c=1; }else{ if(line.c==0) line.b=1; else{ long g = gcd(line.b, line.c); line.b/=g; line.c/=g; } } }else if(line.b==0){ if(line.c==0)line.a=1; else{ long g = gcd(line.a, line.c); line.a/=g; line.c/=g; } }else if(line.c==0){ long g = gcd(line.a, line.b); line.a/=g; line.b/=g; }else{ long g = gcd(gcd(line.a, line.b), line.c); line.a/=g; line.b/=g; line.c/=g; } if(line.a<0 || (line.a==0 && line.b<0)){ line.a = -line.a; line.b = -line.b; line.c = -line.c; } }
求最大共线点数目
int maxPoints(vector<Point>& points) { if(points.size()<3) return points.size(); map<string, set<int>> ma; int ans = 0; for(int i=0;i<points.size();i++){ string s = to_string(points[i].x)+"_"+to_string(points[i].y); ma[s].insert(i); ans = max(ans, (int)ma[s].size()); for(int j=i+1;j<points.size();j++){ if(points[i].x==points[j].x && points[i].y==points[j].y){ string s = to_string(points[i].x)+"_"+to_string(points[i].y); if(ma[s].count(j)==0) ma[s].insert(j); ans = max(ans, (int)ma[s].size()); continue; 4000 } Line cur((long)points[i].y-points[j].y, (long)points[j].x-points[i].x, (long)points[j].x*points[i].y-(long)points[i].x*points[j].y); simplify(cur); string s = to_string(cur.a)+"_"+to_string(cur.b)+"_"+to_string(cur.c); if(ma.find(s)==ma.end()){ set<int> se; se.insert(i); se.insert(j); ma[s]=se; }else{ //cout<<s<<" "<<ma[s].count(i)<<" "<<i<<endl; if(ma[s].count(i)==0) ma[s].insert(i); if(ma[s].count(j)==0) ma[s].insert(j); } ans = max(ans, (int)ma[s].size()); } } return ans; }
总结
在以上处理过程中,需单独考虑某个点重复出现的情况,这时候应该单独计算这些点的数目(同一个点一定共线)。也可以先将这些点的个数统计出来,记录到临时计数器中,当这些点出现在某条直线时,直接从计数器中取出其个数进行叠加等操作。
相关文章推荐
- LeetCode(149) Max Points on a Line
- LeetCode 149 — Max Points on a Line(C++ Java Python)
- [LeetCode]149. Max Points on a Line
- LeetCode 149. Max Points on a Line
- LeetCode(149) Max Points on a Line
- leetCode 149. Max Points on a Line
- leetcode-149. Max Points on a Line
- LeetCode: Max Points on a Line [149]
- leetcode 149. Max Points on a Line 计算斜率的问题 + 直接暴力求解即可
- [LeetCode]149. Max Points on a Line 深入浅出讲解和代码示例
- LeetCode 149. Max Points on a Line
- leetcode_c++:哈希:Max Points on a Line(149)
- [LeetCode]149 Max Points on a Line
- LeetCode 149 Max Points on a Line
- LeetCode 149. Max Points on a Line
- [leetcode] 149. Max Points on a Line
- LeetCode 149. Max Points on a Line
- LeetCode:149_Max Points on a line | 寻找一条直线上最多点的数量 | Hard
- [Leetcode]149. Max Points on a Line @python
- [leetcode-149]Max Points on a Line(java)