题目说明
https://leetcode-cn.com/problems/max-points-on-a-line/description/
给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
解法1
首先遍历点,在第二层循环中使用map记录倾角斜率及其匹配次数。
斜率dx/dy(dx表示两点x轴的距离,dy表示两点y轴的差值)进行计算,但是这里有一种特殊情况,就是dy=0的情况,此种情况下点也在同一直线下,所以需要单独做判断。
还有一种情况就是如果点坐标一致,则不管其他点在什么位置,也需要计入同一直线下,这种情况也需要单独做判断,并且计算总数时需要加上这个点。
/*
* 时间复杂度:O(n^2)
* 使用unordered_map保存倾角斜率以及对应的次数
* 相同的倾角斜率即在同一个直线上
* 注意:需要加上对相同点的处理
*/
int maxPoints(vector<Point>& points) {
int res = 0;
for (int i = 0; i < points.size(); i ++) {
int samenum = 1;
int sameynum = 0;
unordered_map<double, int> map1;
for (int j = i + 1; j < points.size(); j++)
{
//对相同点的判断
if (points[i].y == points[j].y && points[i].x == points[j].x) {
samenum ++;
}
//对分母相等情况进行判断
else if (points[i].y != points[j].y){
//计算倾角
double a = (double)(points[i].x - points[j].x)/(points[i].y - points[j].y);
map1[a] ++;
}
else{
sameynum ++;
}
}
//对只有相同点的情况进行处理
res = max(res,samenum);
//对y相同点情况作处理,需要加上相同点
res = max(res,sameynum + samenum);
//遍历map,取最大值,需要加上相同点
for (unordered_map<double, int>::iterator iter = map1.begin(); iter != map1.end(); iter ++)
{
res = max(res, iter->second + samenum);
}
}
return res;
}
解法2
与第一种解法相比,没有使用dx/dy的方法求斜率,而是使用将dx与dy除以两者的最大公约数,得到化简后的值,比如说6/3、4/2、2/1三者化简后的值是一样的,可视为两点在同一直线上。
/*
* 时间复杂度:O(n^2)
* 使用map保存化简后的dx/dy以及对应的次数
* 相同的dx/dy即在同一个直线上
* 注意:需要加上对相同点的处理
* 最大公约数的计算
*/
int maxPoints2(vector<Point>& points) {
int res = 0;
for (int i = 0; i < points.size(); i ++) {
int samenum = 1;//算上本身
map<pair<int,int>, int> map1;
for (int j = i + 1; j < points.size(); j++)
{
//对相同点的判断
if (points[i].y == points[j].y && points[i].x == points[j].x) {
samenum ++;
}
else{
map1[getpair(points[i], points[j])] ++;
}
}
//对只有相同点的情况进行处理
res = max(res,samenum);
//遍历map,取最大值,需要加上相同点
for (map<pair<int,int>, int>::iterator iter = map1.begin(); iter != map1.end(); iter ++)
{
res = max(res, iter->second + samenum);
}
}
return res;
}
//求化简后的dx/dy
pair<int,int> getpair(Point a, Point b)
{
int dx = a.x - b.x;
int dy = a.y - b.y;
//对x或y相等的判断
if (dx == 0)
return make_pair(0,1);
if (dy == 0)
return make_pair(1,0);
int gcd = getgcd(dx, dy);
dx /= gcd;
dy /= gcd;
return make_pair(dx, dy);
}
//求最大公约数
int getgcd(int a, int b){ return a == 0 ? b : getgcd(b % a, a); }
原文地址:https://www.cnblogs.com/JesseTsou/p/9536903.html
时间: 2024-10-08 16:05:08