给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
输入: [ [ 1 , 1 ], [ 2 , 2 ], [ 3 , 3 ] ]
输出: 3
class Solution {
private:
//获取斜率
//通过string 构造分数,避免精度不正确
//使用最大公约数化简 分子和分母
string getK(int y, int x) {
//y有可能为0,放后面(斜率为0的情况)
int gcdResult = gcd(abs(x), abs(y));
//构建斜率,自判断斜率正负
string result = ((y < 0 && x < 0) || (y > 0 && x > 0)) ? "+" : "-";
//约分
result += to_string(abs(y) / gcdResult) + "/" + to_string(abs(x) / gcdResult);
return result;
}
// 最大公约数
int gcd(int a, int b) {
if (b == 0)
return a;
else
return gcd(b, a % b);
}
public:
int maxPoints(vector<vector<int>>& points) {
if (points.empty())return 0;
int result = 0;
map<string, int> pointMap;//斜率 + 点集合
for (int i = 0; i < points.size(); ++i)
{
int i_x = points[i][0];
int i_y = points[i][1];
int tempResult = 0;
int sampPointNums = 0;//相同位置的点的个数
int KZeroNums = 0;//斜率为不存在的点的个数(j_x-i_x值为0)
for (int j = i + 1; j < points.size(); ++j)
{
int j_x = points[j][0];
int j_y = points[j][1];
if (i_x == j_x && i_y == j_y)
++sampPointNums;
else if (i_x == j_x)
++KZeroNums;
else {
int tempy = j_y - i_y;
int tempx = j_x - i_x;
string&& K = getK(tempy, tempx);
if (pointMap.find(K) == pointMap.end())
pointMap[K] = 1;
else ++pointMap[K];
}
}
//相同斜率的点个数
for (auto&& iter = pointMap.begin(); iter != pointMap.end(); ++iter)
if (iter->second > tempResult)
tempResult = iter->second;
pointMap.clear();
//斜率都不存在的点个数
tempResult = max(tempResult, KZeroNums);
//相同位置的点个数 + 自己
tempResult += sampPointNums + 1;
result = max(result, tempResult);
}
return result;
}
};