LeetCode149. Max Points on a Line
Question:
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
思路:
遍历所有的点,分别计算每个点与其他点的斜率,将这些斜率存储在一个map中并统计数量,最后比较出最大的那个。
例如给一个点A,分别去计算点A与其他点的斜率,总共有三种情况:
- 其他点与点A的坐标相同
- 其他点与点A的横坐标相同,斜率为无穷大
- 正常计算斜率
struct Point {
int x;
int y;
Point() : x(0), y(0) {}
Point(int a, int b) : x(a), y(b) {}
};
int maxPoints(vector<Point> &points) {
int res = 0;
for(int i=0;i<points.size();i++){
int samePoint = 0;
map<double,int> m;
for(int j=0;j<points.size();j++){
if(points[i].x == points[j].x && points[i].y == points[j].y){
samePoint++;
}else if(points[i].x == points[j].x){
m[INT_MAX]++;
}else{
double slope = (1.0*(points[i].y - points[j].y))/(1.0*(points[i].x - points[j].x));
m[slope]++;
}
}
int maxRes = 0;
for(map<double,int>::iterator it = m.begin(); it != m.end(); it++){
maxRes = max(maxRes,it->second);
}
maxRes += samePoint;
res = max(res,maxRes);
}
return res;
}
改进点:
- map改用unordered_map
- 解决失去精度问题,不用斜率作key
- 减少重复计算机,内重循环从i+1开始
struct hashfunc
{
size_t operator() (const pair<int,int>& l) const
{ return l.first ^ l.second; }
};
int gcd(int a, int b) {
if(b==0) return a;
else return gcd(b, a%b);
}
int maxPoints(vector<Point> &points) {
int res = 0;
for(int i=0;i<points.size();i++){
int samePoint = 1;
unordered_map<pair<int, int>,int,hashfunc> m;
for(int j=i+1;j<points.size();j++){
if(points[i].x == points[j].x && points[i].y == points[j].y){
samePoint++;
}else if(points[i].x == points[j].x){
m[make_pair(INT_MAX, INT_MAX)]++;
}else{
int a=points[j].x-points[i].x, b=points[j].y-points[i].y;
int gcdNum=gcd(a, b);
a/=gcdNum;
b/=gcdNum;
m[make_pair(a, b)]++;
}
}
int maxRes = 0;
for(auto it = m.begin(); it != m.end(); it++){
maxRes = max(maxRes,it->second);
}
maxRes += samePoint;
res = max(res,maxRes);
}
return res;
}