【leetcode】149 Max Points on a Line

题目说明

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 maxPoints(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); }
posted @ 2018-08-26 12:55  JESSET  阅读(204)  评论(0编辑  收藏  举报