Given n points on a 2D plane, find the maximum number of points that lie on the same straight line
题意为:给定二维平面上的n个点,找到位于同一直线上的最大点数。
我们都知道,两点可以确定一条直线,而且可以写成y = ax + b的形式,在一条直线上的点都满足这个公式。所以这些给定点两两之间都可以算一个斜率,每个斜率代表一条直线,对每一条直线,带入所有的点看是否共线,并计算个数,这是整体的思路。
当两个点重合时,无法确定一条直线,但这也是共线的情况,需要特殊处理。
当斜率不存在时,由于两个点(x1, y1)和(x2, y2)的斜率k表示为(y2 - y1) / (x2 - x1),那么当x1 = x2时斜率不存在,这种共线情况需要特殊处理。
我们需要用到哈希表来记录斜率和共线点个数之间的映射,其中第一种重合点的情况我们假定其斜率为INT_MIN,第二种情况我们假定其斜率为INT_MAX,这样都可以用map映射了。
- 我们还需要定一个变量duplicate来记录重合点的个数,最后只需和哈希表中的数字相加即为共线点的总数。
方法一:
class Solution {
public:
int maxPoints(vector<Point>& points) {
int res = 0;
for (int i = 0; i < points.size(); ++i)
{
unordered_map<float, int> m;
int duplicate = 1;
for (int j = i + 1; j < points.size(); ++j)
{
if (points[i].x == points[j].x && points[i].y == points[j].y) {
++duplicate;
}
else if (points[i].x == points[j].x)
{
++m[INT_MAX];
}
else
{
float slope = (float)(points[j].y - points[i].y) / (points[j].x - points[i].x);
++m[slope];
}
}
res = max(res, duplicate);
for (auto it = m.begin(); it != m.end(); ++it)
{
res = max(res, it->second + duplicate);
}
}
return res;
}
};
方案二:
class Solution {
public:
int maxPoints(vector<Point>& points) {
int res = 0;
for (int i = 0; i < points.size(); ++i)
{
map<pair<int, int>, int> m;
int duplicate = 1;
for (int j = i + 1; j < points.size(); ++j)
{
if (points[i].x == points[j].x && points[i].y == points[j].y)
{
++duplicate; continue;
}
int dx = points[j].x - points[i].x;
int dy = points[j].y - points[i].y;
int d = gcd(dx, dy);
++m[{dx / d, dy / d}];
}
res = max(res, duplicate);
for (auto it = m.begin(); it != m.end(); ++it)
{
res = max(res, it->second + duplicate);
}
}
return res;
}
int gcd(int a, int b)
{
return (b == 0) ? a : gcd(b, a % b);
}
};
方案三:
class Solution {
public:
int maxPoints(vector<Point>& points) {
int res = 0;
for (int i = 0; i < points.size(); ++i)
{
int duplicate = 1;
for (int j = i + 1; j < points.size(); ++j)
{
int cnt = 0;
long long x1 = points[i].x, y1 = points[i].y;
long long x2 = points[j].x, y2 = points[j].y;
if (x1 == x2 && y1 == y2) {++duplicate; continue;}
for (int k = 0; k < points.size(); ++k)
{
int x3 = points[k].x, y3 = points[k].y;
if (x1 * y2 + x2 * y3 + x3 * y1 - x3 * y2 - x2 * y1 - x1 * y3 == 0)
{
++cnt;
}
}
res = max(res, cnt);
}
res = max(res, duplicate);
}
return res;
}
};