题目: 给你一个数组 points ,其中 = 表示 平面上的一个点。求最多有多少个点在同一条直线上。
本题收获
- 此类题目可以使用分数来表示斜率
- 对分数约分
- 分子分母使用一个int能表示的整数,并利用哈系表保存其(分子分母组合出的唯一值)个数,即可得到相同斜率的个数。
class Solution
{
public:
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int maxPoints(vector<vector<int>> &points)
{
int n = points.size();
if (n <= 2)
return n;
int res = 0;
for (int i = 0; i < n; i++)
{
// 因为第i个节点后最长的直线也只能有n-i个点
// 如果最大的结点数已经达到n的一半了,则没有必要再往后找了
if (n - i <= res || res > n / 2)
break;
unordered_map<int, int> mp; // 使用哈希记录每个斜率数对的个数
for (int j = i + 1; j < n; j++)
{
int x = points[j][0] - points[i][0];
int y = points[j][1] - points[i][1];
if (x == 0)
y = 1;
else if (y == 0)
x = 1;
else
{
if (y < 0)
{
x = -x;
y = -y;
}
int gcdXY = gcd(abs(x), abs(y));
x = x / gcdXY, y = y / gcdXY;
}
// 此处y的范围是[0, 20000],之所以要加上x*20001是因为其值肯定大于y,所以对于不同的x,y总是能得到不同的值。
// 例如y = [1, 2] x = [3, 4] 则x,y取不同的值只会得到唯一值,而y = [1, 2, 3] x = [1, 2, 3] 则x,y取不同的值,可能会得到相同的值
mp[y + x * 20001]++;
}
int maxn = 0;
for (auto &[_, num] : mp)
{
maxn = max(maxn, num + 1);
}
res = max(res, maxn);
}
return res;
}
};