Interesting problem, thanks for posting! Here's my solution. It feels a bit inelegant but I think it meets the problem definition:
Inputs: R
, P = {(x_0, y_0), (x_1, y_1), ..., (x_N-1, y_N-1)}
Output: (u,v)
such that the square with corners (u,v)
and (u+R, v+R)
contains at least 5 points from P
, or NULL if no such (u,v)
exist
Constraint: asymptotic run time should be O(n)
Consider tiling the plane with RxR
squares. Construct a sparse matrix, B
defined as
B[i][j] = {(x,y) in P | floor(x/R) = i and floor(y/R) = j}
As you are constructing B
, if you find an entry that contains at least five elements stop and output (u,v) = (i*R, j*R)
for i,j
of the matrix entry containing five points.
If the construction of B
did not yield a solution then either there is no solution or else the square with side length R
does not line up with our tiling. To test for this second case we will consider points from four adjacent tiles.
Iterate the non-empty entries in B
. For each non-empty entry B[i][j]
, consider the collection of points contained in the tile represented by the entry itself and in the tiles above and to the right. These are the points in entries: B[i][j], B[i+1][j], B[i][j+1], B[i+1][j+1]
. There can be no more than 16 points in this collection, since each entry must have fewer than 5. Examine this collection and test if there are 5 points among the points in this collection satisfying the problem criteria; if so stop and output the solution. (I could specify this algorithm in more detail, but since (a) such an algorithm clearly exists, and (b) its asymptotic runtime is O(1)
, I won't go into that detail).
If after iterating the entries in B
no solution is found then output NULL.
The construction of B
involves just a single pass over P
and hence is O(N)
. B
has no more than N
elements, so iterating it is O(N)
. The algorithm for each element in B
considers no more than 16 points and hence does not depend on N
and is O(1)
, so the overall solution meets the O(N)
target.