1. 程式人生 > >【LeetCode】149. 直線上最多的點數 結題報告 (C++)

【LeetCode】149. 直線上最多的點數 結題報告 (C++)

原題地址:https://leetcode-cn.com/problems/max-points-on-a-line/description/

題目描述:

給定一個二維平面,平面上有 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

 

解題方案:

這題好難,不會做。網上找的解題方式,參考地址給忘了。。。

有幾點值得學習:

  • 雜湊表定義的結構與以往不同,表的key值為座標點,存的是在改直線上點的個數。
  • 解題的主要思路是對點的集合從頭到尾遍歷一次,每次迴圈以當前點為目標,對其他點進行求解斜率k。由於每次確定了一個點的座標,不用再考慮b的大小。這種方法使得計算變得簡單,減少了需要儲存的值,並且每次迴圈結束後,需要對雜湊表進行空間的釋放,也節省了空間。
  • 其實,為了實現快速查詢,map內部本身就是按序儲存的(比如紅黑樹)。在我們插入鍵值對時,就會按照key的大小順序進行儲存。這也是作為key的型別必須能夠進行<運算比較的原因。現在我們用Point型別作為key,因此,我們的儲存順序需要自定義。
  • 雜湊表的key值為Point型別,進行儲存時使用的技巧很巧妙,運用了一點數學技巧。

程式碼:

/**
* 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 gcd(int a, int b) {//最大公約數
        return b ? gcd(b, a % b) : a;
    }
    struct cmp{
        bool operator()(const Point &a, const Point &b){
            return a.x < b.x || (a.x == b.x && a.y < b.y);
        }
    };

    int maxPoints(vector<Point>& points) {
        if (points.empty()) return 0;
        map<Point, int, cmp> A;
        int L = points.size(), ans = 1, n;
        for (int i = 0; i < L; ++i) {
            if (L - i <= ans) 
                break;
            A.clear(); 
            n = 1;
            for (int j = i + 1; j < L; ++j) {
                int a = points[i].x - points[j].x, b = points[i].y - points[j].y;
                if (!(a | b)) { 
                    n ++; 
                    continue; 
                }
                if (!a) 
                    A[Point(0, 1)] ++;
                else if (!b) 
                    A[Point(1, 0)] ++;
                else {
                    int k = gcd(a, b);
                    A[Point(a / k, b / k)] ++;
                }
            }
            ans = max(ans, n);
            for (auto &x : A)
                ans = max(ans, x.second + n);
        }
        return ans;

    }
};