欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Max Points on a Line

程序员文章站 2022-03-29 17:52:04
...

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记录
 *
 * 下面的 2 3 4 9 是dx, dy
 * 问题: 2/3 4/9 这种double类型的斜率在判定时出问题(浮点类型判定相等)
 * 换种思路, 不记录商, 而是记录除最大公因数的结果:
 * eg: (3,2) (6, 4) 记录的都是(3,2) 其实相当于将直线用一个点来表示
 *  特判问题: 斜率为0 和斜率不存在 (gcd函数中实现了特判)
 *           重复点问题: 除了基准点之外的点和基准点坐标相同, 这样的点相当于分布在任何直线上
 * */
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 redundant=1; // 基准点本身也算在直线上的点
            for(int j=i+1;j<points.size();j++){
                if(points[i].x==points[j].x && points[i].y==points[j].y)    redundant++;
                else{
                    int dx = points[j].x - points[i].x;
                    int dy = points[j].y - points[i].y;
                    int tmp = gcd(dx, dy);
                    m[{dx/tmp, dy/tmp}]++;
                }
            }
            ret = max(ret, redundant); // 很特殊的情况: map为空 即所有剩余点都和基准点重合
            for(auto &it : m){
                ret = max(ret, it.second+redundant);
            }
        }
        return ret;
    }
    int gcd(int a, int b){// dy=0, 返回dx, dx=0, 返回dy....刚好不用再进行特判
        return b==0 ? a : gcd(b, a%b);
    }
};