题目描述
给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
示例 1:
输入: [[1,1],[2,2],[3,3]] 输出: 3 解释: ^ | | o | o | o +-------------> 0 1 2 3 4
示例 2:
输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] 输出: 4 解释: ^ | | o | o o | o | o o +-------------------> 0 1 2 3 4 5 6
问题分析
此题给了一个数组,数组中每一个元素都是一个点。我们遍历这个数组,分别以每个点为基准,算出其他各点与此基准点在一条直线上的最多有多少个点,然后再加上与基准点重合的点的个数(包括基准点本身),就得到了以当前基准点形成的直线最多有多少个点,为局部最优解。接下来把数组中所有点分别作为一次基准点,进行上述操作,用得到的所有局部最优得到全局最优解ans并返回。用红黑树map记录斜率和点的个数之间的映射,其中斜率是用pair<int, int>表示的,计算出的斜率要除以最大公约数才可以保存进map中。当遇到点与基准点重合时,不计算斜率,而是将dup加1,当遍历完其他各点得到temp后,再将dup加上,得到局部最优解。
代码实现
/**
* 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:
int maxPoints(vector<Point>& points) {
int ans = 0;
for(int i = 0; i < points.size(); i++){
map<pair<int, int>, int> m;
int dup = 0;
int temp = 0;
for(int j = 0; j < points.size(); j++){
int dx = points[j].x - points[i].x;
int dy = points[j].y - points[i].y;
if(dx == 0 && dy == 0)
dup++;
else{
int g = gys(dx, dy);
++m[make_pair(dx / g, dy / g)];
}
}
for(auto a : m)
temp = max(temp, a.second);
temp += dup;
ans = max(ans, temp);
}
return ans;
}
int gys(int a, int b){
return (b == 0)? a : gys(b, a % b);
}
};