您的位置:首页 > 其它

leetcode Max Points on a Line

2014-07-16 15:55 423 查看
给一堆点,找在同一条直线上最多的点数。

其实也不难,按照斜率来就是了。

100个点130ms左右,居然TLE了。

只好找找看有没有别的更好的办法。

有人提出用霍夫变换做,看起来确实是一个好办法。

霍夫变换的基本是,过某一个点的直线可以表示成 y = kx + b,那么把k和b当做参数的空间里,过这个点的所有直线在k-b空间中就是一条直线。过第二个点的所有直线在k-b空间也是一条直线,这两条直线的交点值k,b就是这两个点连线的参数k,b。

所以把所有n个点转换到霍夫空间,就是n条直线;找这n条直线的交点中有最多直线相交的交点,就是我们要找的过最多个点的直线参数k,b。

但是因为y=kx+b不能表示垂直的直线,所以一般用p=x*cos(theta)+y*sin(theta)也就是弧度空间来计算。

这样看来,这n个点变成了p,theta空间的n对参数,目的是要找这n条直线的交点中包含最多直线的交点。

也就是,x1*cos(theta)+y1*sin(theta) = x2*cos(theta)+y2*sin(theta),已知x1,y1,x2,y2,求theta。

可是theta不好求。所以有人想出枚举的办法:

#define computeRho( pt, T ) ( ( pt.x * cos( T ) ) + ( pt.y * sin( T ) ) )

class Solution {
public:
int maxPoints(vector<Point> &points) {
if ( points.size() <= 2 ) {
return points.size();
}
int max_points = 0;
for ( int i = 0; i < 180; i++ ) {
double theta = double( i ) / 180.0 * 3.141592657;
map<int,int> accumulator;
for ( int j = 0; j < points.size(); j++ ) {
int rho = round( computeRho( points[j], theta ) );
accumulator[ rho ]++;
if ( accumulator[ rho ] > max_points ) {
max_points = accumulator[ rho ];
}
}
}
return max_points;
}
};


这样时间复杂度就是O(180N)。

但是测试花的时间比我的还多。。

hash_map在leetcode居然不能用!

这道题真折腾人,相同的点要重复计算。。 最后还是按照测试数据量身定制了一个方法,钻空子了又。。

int findMax(vector<Point> &points)
{
if ( points.size() <= 2 ) {
return points.size();
}
int i,j,k;
int result = 0;
float fmax = 4294967295.0f;

for (i = 0; i < points.size();i++)
{
int samecount = 0, flag = 0;
unordered_map<float,int> line;
for (j = i+1; j < points.size();j++)
{
float g,tmp;
int xv = points[i].x - points[j].x;
int yv = points[i].y - points[j].y;

//same points
if(xv == 0 && yv == 0){samecount++; continue;}

//perpendicular with x axis
if(xv == 0)
{
g = fmax;
}
else if(yv == 0)//parallel with x axis
{
g = 0;
}
else
{
g = (float)yv / (float)xv;
}

if(line[g] == NULL){
line[g] = 2;
}
else{
line[g]++;
}
if(line[g] > result){ result = line[g]; flag = 1;}
}
if(flag) result += samecount;
else if(samecount > result) result = samecount + 1;
}

return result;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: