zoukankan      html  css  js  c++  java
  • LeetCode 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.

     强行解:

    inline bool valueSame(double a, double b) {
        return abs(a - b) < 0.01;
    }
    
    class Line {
    public:
        double k;
        double d;
        bool infiniteK;
        Line(){};
        Line(double _k, double _d) : k(_k), d(_d), infiniteK(false) {}
        Line(double _k) : k(_k), d(0.0), infiniteK(true) {}
        
        bool operator==(const Line& line) const {
            if (infiniteK != line.infiniteK) {
                return false;
            } else if (line.infiniteK) {
                return valueSame(k, line.k);
            }
            return valueSame(k, line.k) && valueSame(d, line.d);
        }
    };
    
    struct LineHashFunc {
        size_t operator() (const Line& line) const {
            return  (std::hash<double>()(line.k))
            ^ (std::hash<double>()(line.d))
            ^ (std::hash<bool>()(line.infiniteK));
        }
    };
    
    struct PointHashFunc {
        size_t operator() (const Point& point) const {
            return (hash<int>()(point.x)) ^ (hash<int>()(point.y) << 1);
        }
    };
    
    struct PointEqualFunc {
        bool operator()(const Point& a, const Point& b) const {
            return valueSame(a.x, b.x) && valueSame(a.y, b.y);
        }
    };
    
    
    class Solution {
    public:
        unordered_map<Line, unordered_set<int>, LineHashFunc> pts;
        int line_count;
        Line maxline;
        
    public:
        int maxPoints(vector<Point>& points) {
            pts.clear();
            line_count = 0;
            unordered_map<Point, int, PointHashFunc, PointEqualFunc> pnums;
            int max_pnums = 0;
            for (Point& p : points) {
                max_pnums = max(max_pnums, ++pnums[p]);
            }
            int len = points.size();
               
            for (int i=0; i<len; i++) {
                Point& a = points[i];
                vector<Line> lines;
                for (int j = i + 1; j<len; j++) {
                    Point& b = points[j];
                    if (valueSame(a.x, b.x)) {
                        if (!valueSame(a.y, b.y)) {
                            lines.push_back(Line(a.x));
                            inc(lines.back(), i, j);
                        } else {
                            for (Line line : lines) {
                                inc(line, i, j);
                            }
                        }
                        continue;
                    }
                    double k = (a.y - b.y) * 1.0 / (a.x - b.x);
                    double d = a.y - k * a.x;
                    lines.push_back(Line(k, d));
                    inc(lines.back(), i, j);
                }
            }
            return max(max_pnums, line_count);
        }
        
        void inc(Line a, int ia, int ib) {
            if (!pts.count(a)) {
                pts[a] = unordered_set<int>();
            }
            
            pts[a].insert(ia);
            pts[a].insert(ib);
            
            if (pts[a].size() > line_count) {
                line_count = pts[a].size();
                maxline = a;
            }
        }
    };

    能把程序写成这样真是太忧伤了。以上是从全局的角度考虑,等算出所有可能的直线后进行最大值提取。

    从discuss中找了个高大上的:从局部考虑,过一点,再加个斜率,一条直线就确定了,逐步计算过这些线的点,取最大的即可。

    /**
     * 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 len = points.size();
            if (len <= 2) {
                return len;
            }
            int maxon = 0;;
            for (int i=0; i<len; i++) {
                Point& a = points[i];
                unordered_map<double, int> lines;
                int normal = 1;
                int vertical = 1;
                int duplicate= 0;
                for (int j=i+1; j<len; j++) {
                    Point& b = points[j];
                    if (a.x == b.x) {
                        if (a.y == b.y) {
                            duplicate++;
                        } else {
                            vertical++;
                        }
                    } else {
                        double k = (a.y - b.y) * 1.0 / (a.x - b.x);
                        lines[k] += !lines[k] + 1;
                        normal = max(normal, lines[k]);
                    }
                }
                maxon = max(maxon, max(normal + duplicate, vertical + duplicate));
            }
            return maxon;
        }
    };
  • 相关阅读:
    AngularJS Insert Update Delete Using PHP MySQL
    Simple task manager application using AngularJS PHP MySQL
    AngularJS MySQL and Bootstrap Shopping List Tutorial
    Starting out with Node.js and AngularJS
    AngularJS CRUD Example with PHP, MySQL and Material Design
    How to install KVM on Fedora 22
    Fake_AP模式下的Easy-Creds浅析
    河南公务员写古文辞职信
    AI
    政协委员:最大愿望是让小学生步行上学
  • 原文地址:https://www.cnblogs.com/lailailai/p/4580310.html
Copyright © 2011-2022 走看看