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;
    }
};
原文地址:https://www.cnblogs.com/lailailai/p/4580310.html