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;

    }

};

 

你可能感兴趣的:(LeetCode)