您的位置:首页 > 其它

LeetCode(149)Max Points on a Line

2014-03-07 13:49 344 查看
题目如下:

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

思考分析:

一开始,我觉得这道题不是考算法的,题目确实不涉及算法的内容。但是后来,我交了很久才成功,才明白这道题的坑点在于corner cases.

首先,看解题方法。

假设在全部的n个点种,选定某一个点i,然后计算从i点到剩下的n-1个其它点构成的直线的斜率,如果[i, j1], [i, j2], [i, j3]斜率相同,显然i, j1, j2, j3就位于同一条直线上。用一

个map 来统计,斜率相同的点j1, j2, j3有多少个

但是其实点i不是固定的一点,它可以是n个点种的任何一个。所以在上面的循环外,再写一个循环。

基本思路如上。很直观。

然后,看坑点。

坑点1 如果直线是和y轴平行的,那么不能直接用(y1-y2)/(x1-x2)表示斜率,可以用INT_MAX表示斜率。

坑点2 如果有重复的点,如何处理。如[1,1], [2,2], [1,1],这是这道题目最关键的一点的,需要想清楚。对于选定的点i,在接下来计算定点i到剩下的n-1个点构成的斜率的时候,如果出现某点k和点i是相同的点,那么可以知道,点k将和任意一条和i共线的线共线,也就是说,需要单独用一个变量same_point_num来计数,看看和i相同的点有多少个,最后 在map中求了最多共线点后再加上same_point_num

坑点3 如何表示斜率相同的一堆点。注意点的坐标是int,斜率为了精确,需要设定为float或者double,这里涉及到精度转换的问题。

我的代码:

//104ms过大集合
/**
 * 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) {
        if(points.size()==0)
            return 0;
        int max_num=0;
        int same_point_num=0;
        for(int i=0;i<(int)points.size();i++){
            map<double,int> slope_map;
            same_point_num=0;
            for(int j=0;j<(int)points.size();j++){
                if(j==i) // i和i自己不需要计算
                    continue;
                if(points[i].x-points[j].x==0&&points[i].y-points[j].y==0) //相同点
                    same_point_num++;
                else if(points[i].x-points[j].x==0&&points[i].y-points[j].y!=0) //斜率为tan90°的点
                    slope_map[INT_MAX]++;
                else
                    slope_map[double(points[j].y-points[i].y)/(points[j].x-points[i].x)]++; //正常点,注意double写的位置
            }
            int tmp_max=0;
            for(map<double,int>::iterator it=slope_map.begin();it!=slope_map.end();it++){ //找到map中含有最多的点的斜率
                if(it->second>tmp_max)
                    tmp_max=it->second;
            }
            if(tmp_max+same_point_num>max_num) //用map中的最多点再加上same_point_num得到的数和历史的最大值做比较跟新历史最大值
                max_num=tmp_max+same_point_num;
        }
        return max_num+1;//当max_num为1时,确定了1条直线,2个点;当max_num为2时,确定了3个点;当max_num为i时,确定了i+1个点。
    }
};


小结扩展:

(1) int a, int b

double c1=(double)(a/b);

double c2=(double)a/b;

一个需要注意细节的问题。上面的表达式中,c1返回的是int提升为double后的值,如5/2,返回的是2.0,这不是本题想要的结果。 c2返回的是5/2=5.0/2=2.5,是本题想要的结果。要注意这种细节方面的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: