给出n个2D点。考虑通过连接任何一对这些点创建的所有可能的段。如何在O(n * log(n))中找到所有可能段中具有最大斜率的段?
我们可以根据x和/或y坐标对数组进行排序吗?
找到y_i
和y_j
,以便y_i - y_j
是最大差异,并找到斜率(让它为delta_y
);
找到x_k
和x_l
,x_k - x_l
最小,并找到斜率(让它为delta_x
);
返回x和y坐标max(delta_y, delta_x)
。
这是对的吗?
答案 0 :(得分:3)
斜率是(delta_y)/(delta_x)
的比率,其中delta_y
和delta_x
是在相应点之间测量的。
您的方法计算的比率为(y_i - y_j)/(x_k - x_l)
,i
,j
,k
和l
最大化y_i - y_j
和{{1} }}。但请注意,x_k - x_l
或(x_k, y_i)
都不可能是给定(x_l, y_j)
点中的点数。也就是说,您的方法不会在相应的点上衡量n
和delta_y
。
要获得有效的方法,请考虑按delta_x
坐标按升序对点进行排序,这需要O(n log n)时间。然后在O(n)时间内测试任何两个点是否具有相同的x
坐标。如果是这样,则存在无限或不确定的斜率。否则,考虑连续点之间的斜率。可以证明,当点按升序x
排序时,任意两个n
点之间最陡的斜率出现在连续点之间。因此,在使用O(n log n)时间对点进行排序后,可以在O(n)时间内找到最大斜率。
答案 1 :(得分:2)
我想你可以。考虑三个连续点。从第一点到第三点绘制直线,并查看中间点是在其上方,中间还是下方。如果中间点在线上,则所有斜率都相等。如果中间点在线上方,则从第一点到第二点的斜率最高。如果中间点在线下方,则从中间点到第二个的斜率最高。在任何情况下,您都可以找到两个相邻点之间的最大斜率。
答案 2 :(得分:0)
我不知道这是否有效。答案是开放的建议和编辑。
我将使用Divide and Conquer。
P是所有点的集合。
MAX_SLOPE(P)
sort all the points in P according to ascending X coordinate and break ties using ascending Y coordinates.
print(FIND_MAX_SLOPE(P))
FIND_MAX_SLOPE(P)
if(P.length == 2)
if(p1.x-p2.x != 0)
return (p1.y-p2.y)/(p1.x-p2.x)
else
return 0
else
left_p = P[0..P.length/2]
right_p = P[P.length/2..P.length]
slope_left = FIND_MAX_SLOPE(left_p)
slope_right = FIND_MAX_SLOPE(right_p)
slope_across_border = FIND_MAX_SLOPE(left_p.last UNION right_p.first)
return MAX(slope_left,slope_right,slope_across_border)