Max Points on a Line(直线上最多的点数)

给定一个二维平面,平面上有 个点,求最多有多少个点在同一条直线上。

示例 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

看到此题,第一想法是用一个数据结构来表示某一条直线,直线的表达式有y = ax + b ,那提取出 a和b是不是就可以了,写完发现还有x = 1这种直线。然后想通过hashmap来保存直线对应的点数,如果参数a和b是个1/3这种值,由于精度问题,算出来的两个直线的数据结构的hash值就不一样,hashmap就是认为是两个key。 最后无奈换成分数表达式 y = (a1/a2)*x + b1/b2;   b1/b2 = (a2*y - a1*x)/a2;这样4个int变量,就可以精确表示一条直线.当然,分数需要进行约分!
struct FPoint {
    int a1;
    int a2;
    int b1;
    int b2;
    FPoint() : a1(0), a2(0), b1(0), b2(0) {}
    FPoint(int _a1, int _a2)
    {
        if (_a1 * _a2 > 0)
        {
            a1 = abs(_a1);
            a2 = abs(_a2);
        }
        else
        {
            a1 = -1 * abs(_a1);
            a2 = abs(_a2);
        }
        b1 = 0;
        b2 = 1;
    }
    bool Contain(Point p)const
    {
        long long int t1 = 1L, t2 = 1L;
        t1 = t1 * p.y * (a2*b2);
        t2 = t2 * a1*b2*p.x + b1*a2;
        return a2 == 0 ? p.x == b1 / b2 : t1 == t2;
    }
    void Normal()
    {
        if (a1 == 0 && a2 == 0)
        {
        }
        else if (a1 == 0)
            a2 = 1;
        else if (a2 == 0)
            a1 = 1;
        else
        {
            int s = a1*a2 > 0 ? 1 : -1;
            a1 = abs(a1);
            a2 = abs(a2);
            int _gcd = GCD(a1, a2);
            a1 = s * a1 / _gcd;
            a2 = a2 / _gcd;

            if (b1 == 0)
                b2 = 1;
            else
            {
                s = b1*b2 > 0 ? 1 : -1;
                b1 = abs(b1);
                b2 = abs(b2);
                _gcd = GCD(b1, b2);
                b1 = s * b1 / _gcd;
                b2 = b2 / _gcd;
            }
        }

    }  //最大公约数
    int GCD(int a, int b){
        int m = a, n = b, r;
        if (m < n){
            int temp = m;
            m = n;
            n = temp;
        }
        r = m % n;
        while (r){
            m = n;
            n = r;
            r = m % n;
        }
        return n;
    }
};
struct RecordHash
{
    size_t operator()(const FPoint& f) const{
        return hash<int>()(f.a1) ^ hash<int>()(f.a2) ^ hash<int>()(f.b1) ^ hash<int>()(f.b2);
    }
};
struct RecordCmp
{
    bool operator()(const FPoint& f1, const FPoint& f2) const{
        return f1.a1 == f2.a1 && f1.a2 == f2.a2 &&f1.b1 == f2.b1&&f1.b2 == f2.b2;
    }
};

class Solution {
public:
   FPoint GetPoint(Point a, Point b)
    {
        FPoint f(b.y - a.y, b.x - a.x );
        if (f.a2 == 0)
        {
            f.b1 = a.x;
            f.b2 = 1;
        }
        else
        {
            f.b1 = (f.a2*a.y - f.a1*a.x);
            f.b2 = f.a2;
        }
        return f;
    }
    int maxPoints(vector<Point>& points) {
        if (points.size() <= 1)
        {
            return points.size();
        }
        unordered_set<int> index_set;
        unordered_map<FPoint, int, RecordHash, RecordCmp> line_map;
        int max_point = 0;
        for (int i = 0; i < points.size(); i++)
        {
            unordered_map<FPoint, int, RecordHash, RecordCmp>::iterator itr = line_map.begin();
            for (; itr != line_map.end(); itr++)
            {
                if (itr->first.Contain(points[i]))
                {
                    itr->second++;
                    max_point = max(max_point, itr->second);
                    if (index_set.count(i) == 0)index_set.insert(i);
                }
            }
            for (int r = 0;  r < points.size() ; r++)
            {
                if (r != i && index_set.count(r) == 0)
                {
                    FPoint f = GetPoint(points[i], points[r]);
                    f.Normal();
                    if (line_map[f] == 0)
                    {
                        line_map[f]++;
                    }
                    if (index_set.count(i) == 0)
                    {
                        index_set.insert(i);
                    }
                    max_point = max(max_point, line_map[f]);
                }
            }
        }
        return max_point;
    }
};

原文地址:https://www.cnblogs.com/shit/p/9713681.html

时间: 2024-11-07 15:49:01

Max Points on a Line(直线上最多的点数)的相关文章

149 Max Points on a Line 直线上最多的点数

给定二维平面上有 n 个点,求最多有多少点在同一条直线上. 详见:https://leetcode.com/problems/max-points-on-a-line/description/ /** * 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 {

[Swift]LeetCode149. 直线上最多的点数 | 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]

UVA Lining Up (一条直线上最多的点数)

Description  Lining Up  ``How am I ever going to solve this problem?" said the pilot. Indeed, the pilot was not facing an easy task. She had to drop packages at specific points scattered in a dangerous area. Furthermore, the pilot could only fly over

leetcode 149. 直线上最多的点数

这题卡了好长时间,心态崩了呀,,, 最开始把斜率当作直线,我真是脑抽,表示一条直线用斜率 k + 截距 b 就可以了. 但是要注意,如果两点x值相等,那么我们斜率为正无穷,为了能表示不同的与x轴垂直直线,用x坐标表示一条与x轴垂直的直线:如果两点y值相等,那么我们的斜率为0,为了表示,则用y值表示不同的直线. 对于一般直线就用k b表示,题中的数据有坑的地方,两点相等也是同一条直线,我们用不同的下标区分坐标相同的点就可以了. class Solution { public: int maxPoi

Max Points on a Line leetcode java

题目: Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. 题解: 这道题就是给你一个2D平面,然后给你的数据结构是由横纵坐标表示的点,然后看哪条直线上的点最多. (1)两点确定一条直线 (2)斜率相同的点落在一条直线上 (3)坐标相同的两个不同的点 算作2个点 利用HashMap,Key值存斜率,Value存此斜率下的点的个数.同时考虑特殊情况,如

[leetcode]Max Points on a Line @ Python

原题地址:https://oj.leetcode.com/problems/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. 解题思路:找到平面上在一条直线上最多的点.点在同一条直线上意味着这些点的斜率是一样的,那么可以考虑使用哈希表来解决,{斜率:[点1,点2]}这样的映射关系.这里有几个需要考虑

LeetCode: Max Points on a Line [149]

[题目] Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. [题意] 给定一堆点,要求找出一条之前上的最大点数 [思路] 没什么好的方法,从每个点P出发,遍历所有的情况 从每个点P出发,斜率相同的点即为统一之前上的点 注意两种特殊情况: 1. 两个点重合(即为同一个点) 2. 两个点的很坐标相同,即两天构成的之前垂直于X轴 [代码] /** * D

[LeetCode][JavaScript]Max Points on a Line

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. 求有多少点在一直线上. 粗暴地用二重循环遍历. 每一轮都构造一个哈希表,用来记录斜率,斜率k = (y1 - y2) / (x1 - x2). 注意到特殊情况: 1.两点重合,用countSamePoint记下重复的点,最后加到结果上. 2.两点与X轴平行,

LeetCode:Max Points on a line

题目: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. 这道题需要稍微转变一下思路,用斜率来实现,试想找在同一条直线上的点,怎么判断在一条直线上,唯一的方式也只有斜率可以完成,我开始没想到,后来看网友的思路才想到的,下面是简单的实现:其中有一点小技巧,利用map<double, int>来存储具有相同斜率