支线任务-6

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.

题目简洁易懂,给二维平面上的 n 个点,要找出一条包含最多点的直线,并返回这个点数。

最直接的想法就是枚举每条可能的直线然后判断其他点在这条直线上的有多少个,这样复杂度是O ( n)。

但是其实如果对于每个点统计出了这个点到其他所有点的斜率,就可以当作一个斜率列表来看,这样我们实际上是在这个列表中寻找一个出现次数最多的元素的出现次数。这样复杂度就取决于这个数据结构的查找速度了。比如使用平衡树的话可以在O ( logn )时间找出最大,所以是O ( n2logn )完成题目。也有一些插入和查找都只要O ( n ) 的数据结构,这样就能优化到O ( n2 )。

当然了,有一些细节需要处理,比如当遇到重点或者垂直共线的时候,需要特殊记录一下然后比较。

下面使用STL中的平衡树完成题目

/**
 * 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 max(int a, int b) {return a > b ? a : b;}
    int maxPoints(vector<Point>& points) {
        int ans = 0;
        for (int i = 0; i < points.size(); i++) {
               int sameLine = 1, samePoint = 1, cnt = 0;
            multiset<double> q;
            for (int j = 0; j < points.size(); j++) {
                if (i == j) continue;
                // 如果是同一个点
                if (points[i].x == points[j].x && points[i].y == points[j].y) {
                    samePoint++;
                    continue;
                }
                // 如果垂直共线
                if (points[i].x == points[j].x) {
                    sameLine++;
                    continue;
                }
                q.insert(((double)(points[i].y - points[j].y) / (points[i].x - points[j].x)));
            }
            for (multiset<double>::iterator it = q.begin(); it != q.end(); ++it) {
                cnt = max(cnt, (unsigned int)q.count(*it));                
            }
            // 某一条线上的点数、垂直线上的点数
            cnt = max(cnt + samePoint, sameLine + samePoint - 1);
            ans = max(ans, cnt);
        }
        return ans;
    }
};

如果把其中的multiset替换成unordered_map就可以实现O ( n2 )

posted @ 2015-12-11 03:06  lustralisk  阅读(209)  评论(0编辑  收藏  举报