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;
        }
    };
  • 相关阅读:
    使用Mockito进行单元测试【2】—— stub 和 高级特性[转]
    使用Mockito进行单元测试【1】——mock and verify[转]
    一个更加简洁的 建造者模式
    建造者模式
    另一种 模板模式
    模板模式
    适配器模式的另一种解释
    适配器模式
    迭代器模式
    迭代器模式 循环数组
  • 原文地址:https://www.cnblogs.com/lailailai/p/4580310.html
Copyright © 2011-2022 走看看