149. Max Points on a Line

问题描述:

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

Example 1:

Input: [[1,1],[2,2],[3,3]]
Output: 3
Explanation:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3  4

Example 2:

Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
Output: 4
Explanation:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6

 

 

解题思路:

这道题让我们找在一条直线上的点的最多的数目。

很容易我们想到把点和其所在的直线构成一个键值对放到map中。

问题是,如何表示直线?

若用y = kx + b来表示, x = c则无法表示。

一开始我用Ax + By + C =0来表示直线,自己构造了一个struct来存放参数,并且自己写了struct的hash方法,来存入unordered_map中。(见C++11 unordered_set & unordered_map 存储结构体(struct)

我通过 A = y1 - y2 B = x2- y1 C = x1y2 - x2y1来计算,但是这样会出现一个问题,就是由于点的相对距离不同, 明明在一条直线上却会被认为不在一条直线上。

参考了discussion中的16ms/28ms C++ Solutions with Explanations的答案

这里用一个pair来存储dx,dy的值,为了避免上述情况的发生,对dx 和 dy求了最大公约数并进行约分。

同时注意的是,为了避免重复计算多个点,在外部循环时创建map,一次循环结束时找到最大值存储起来。

还需要注意的是:若两点重合,虽然不能构成线,但是可以认为落在同一条直线上。

关于如何找到最大公约数:求最大公约数的算法

 

代码:

/**
 * 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 maxPoints(vector<Point>& points) {
        int ret = 0;
        for(int i = 0; i < points.size(); i++){
            map<pair<int,int>, int> m;
            int duplicate = 1;
            for(int j = i+1; j < points.size(); j++){
                if(points[i].x == points[j].x && points[i].y == points[j].y){
                    duplicate++;
                    continue;
                }
                int dx = points[i].x - points[j].x;
                int dy = points[i].y - points[j].y;
                int div = gcd(dx, dy);
                m[{dx/div, dy/div}]++;
            }
            ret = max(duplicate, ret);
            for(auto p:m){
                ret = max(ret, (p.second+duplicate));
            }
        }
        
        return ret;
    }
private:
    int gcd(int a, int b){
        while(b){
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }
};

 

posted @ 2018-06-24 00:21  妖域大都督  阅读(128)  评论(0编辑  收藏  举报