Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
Example 1:
Input: [[1,1],[2,2],[3,3]] Output: 3 Explanation: ^ | | o | o | o +-------------> 0 1 2 3 4
Example 2:
Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] Output: 4 Explanation: ^ | | o | o o | o | o o +-------------------> 0 1 2 3 4 5 6
同样的是牛客上通过leetcode上通不过,另外这题目居然是hard级别的,不怪我做不出来了:D
首先贴出最后AC的代码:
class Solution {
public:
int maxPoints(vector<Point> &points) {
if (points.size() == 0)
return 0;
if (points.size() == 1)
return 1;
int res = 0;
for (int i = 0; i < points.size(); i++)
{
int SamePoints = 0, KnotExist = 0;
int Curmax = 1;
map <pair<int, int>, int> lines;
for (int j = 0; j < points.size(); j++)
{
if (j != i) {
int x_diff = points[i].x - points[j].x;
int y_diff = points[i].y - points[j].y;
if (x_diff == 0 && y_diff == 0)
SamePoints++;
else if (x_diff == 0) {
if (KnotExist == 0)KnotExist = 2;
else KnotExist++;
if (Curmax < KnotExist) {
Curmax = KnotExist;
}
}
else {
//double k = y_diff / x_diff;
int div = gcd(abs(x_diff), abs(y_diff));
x_diff /= div; y_diff /= div;
pair<int, int> Curpair(x_diff, y_diff);
if (lines[Curpair] == 0) {
lines[Curpair] = 2;
}
else lines[Curpair]++;
if (Curmax < lines[Curpair])
Curmax = lines[Curpair];
}
}
if (res < Curmax + SamePoints)
res = Curmax + SamePoints;
}
}
return res;
}
private:
int gcd(int x_diff, int y_diff) {
if (y_diff == 0)
return x_diff;
else {
if (x_diff < y_diff) {
int tmp = x_diff; x_diff = y_diff; y_diff = tmp;
}
return gcd(y_diff, x_diff%y_diff);
}
}
};
此题最关键的点是能够对点进行分类:
相同位置的点(用SamePoints表示),斜率相同的点(使用一个map表示),斜率不存在(垂直的点,KnotExist表示)。
在一个二重大循环里,第一层循环指定一个点,在第二层循环里计算它和其他点的情况:垂直,重合,在或不在一条直线上。
一开始写的时候直接把斜率算出来了,用一个double k表示,然而:
主要的问题是map <double, int> lines;的精度不够,测试用例如下:
Input:[[0,0],[94911151,94911150],[94911152,94911151]]
Output:3
Expected:2
这里还有一个问题就是写了好多遍的GCD依然记不得咋写,这次真的要记住了。