1. 程式人生 > >【leetcode】149 Max Points on a Line

【leetcode】149 Max Points on a Line

air http vector 解法 相同 iter 遍歷map com 匹配

題目說明

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); }

【leetcode】149 Max Points on a Line