欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LeetCode | 149. Max Points on a Line求多个点里面在一条直线上的点最多有多少个难题

程序员文章站 2022-04-01 18:41:34
...

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

感觉我的想法太复杂了,不过暂时也只想得到这个方法,

我的方法大概的原理是两点决定一条直线,首先遍历原点数组,将其中的相同的点复制到另外一个点数组里面去,这样另外一个点的数组就不会有重复的点,

然后根据两个点决定一条直线,遍历点数组里面的点,看那些点在同一条直线上面,统计直线上面点的数量,接下来已经在直线上面的点就不需要遍历了,只需要遍历那些没有确定在哪条直线上的点就行了。

当所有的点都遍历完毕之后,所有的直线也就确定了,点最多的一条直线也就能够直接得到

这里还需要注意的是如何判断三个点共线,这里不能使用浮点数相除,因为精度的原因会导致错误,也不能把int赋给float,因为当int比较大的时候,将int赋给float会导致误差,所以只能考虑其他的方法来判断三点是否共线

由于三点的坐标都是int,所以可以取其中的两个点,求其横坐标差和纵坐标差的最大公约数,然后除以最大公约数,将待比较的点的坐标除以这个结果,如果除以的结果相等,这三点就共线,如果不相等,这三个点就不共线,处理这一步的时候还需要注意坐标可能会为负数

坐标为0的时候也要特别处理

以后做题的时候要尽量避免将int转换成float,要尽量避免int相除,要尽量避免将int转换成float,要尽量避免if等于号里面出现float运算!

/**
 * 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:
     bool checkOnLine(int xL, int yL, int tmpX, int tmpY)
{
	 int a, b,tmp;
	 if (yL == 0 && tmpY == 0) return true;
	 if (xL == 0 && tmpX == 0) return true;
	 if (yL != 0 && tmpY != 0&& xL != 0 && tmpX != 0)
	 {
		 a = xL, b = yL;
		 while (a%b != 0)
		 {
			 tmp = a%b;
			 a = b;
			 b = tmp;
		 }
		 b = abs(b);
		 a = xL / b;
		 b = yL / b;
		 if (tmpX%a == 0 && tmpY%b == 0 && tmpX / a == tmpY / b)
			 return true;
	 }
	 return false;
}
 int getThePointN(int one,int two, vector<Point>& points, vector<vector<int>> & thePointMark, vector<int> &pointsSameCount)
{
	 int xL, yL,tmpX,tmpY;
	 int pCount = pointsSameCount[one]+ pointsSameCount[two];
	 vector<int> thePointW;
	 thePointW.push_back(one);	 thePointW.push_back(two);
	 xL = points[one].x - points[two].x;
	 yL = points[one].y - points[two].y;
	 for (int i = 0; i < points.size(); i++)
	 {
		 if (i != one&&i != two)
		 {
			 tmpX = points[i].x - points[one].x;
			 tmpY = points[i].y - points[one].y;
			 if (checkOnLine(xL,yL,tmpX,tmpY))
			 {
				 pCount+= pointsSameCount[i];
				 thePointW.push_back(i);
			 }
		 }
	 }
	 for (int i = 0; i<thePointW.size()-1; i++)
		 for (int j = i + 1; j <thePointW.size(); j++)
		 {
			 thePointMark[i][j] = pCount;
			 thePointMark[j][i] = pCount;
		 }
	 return pCount;
}
int maxPoints(vector<Point>& points) {
	int n = points.size();
	vector<Point> pointsNoSame;
	vector<bool> checkTheSame(n, false);
	vector<int> pointsSameCount;
	for (int i = 0; i < n; i++)
	{
		if (!checkTheSame[i])
		{
			int tmp = 1;
			for (int j = i + 1; j < n; j++)
			{
				if (points[i].x == points[j].x&&points[i].y == points[j].y)
				{
					checkTheSame[j] = true;
					tmp++;
				}

			}
			pointsNoSame.push_back(points[i]);
			pointsSameCount.push_back(tmp);
		}
	}
	n = pointsNoSame.size();
	if (n == 0) return 0;
	if (n == 1) return pointsSameCount[0];
	vector<vector<int>> thePointMark(n, vector<int>(n, -1));
	int theMaxN = 0;
	for(int i=0;i<n-1;i++)
		for (int j = i + 1; j < n; j++)
		{
			if (thePointMark[i][j] == -1)
			{
				theMaxN = max(getThePointN(i,j, pointsNoSame,thePointMark, pointsSameCount), theMaxN);
			}
		}
	return theMaxN;
}
};