Problem Description
Given a square with side length side (with corners (0,0), (0,side), (side,0) and (side,side)) and a list of unique points (each guaranteed to lie on the square’s boundary), choose k of these points so that the minimum Manhattan distance between any two chosen points is as large as possible. Return this maximum possible minimum distance.
Key Insights
- The points lie on the boundary so they have an intrinsic cyclic (or “perimeter”) order.
- The problem asks for maximizing a “minimum” pairwise distance; such problems are often solved using binary search on the answer.
- For a candidate distance d, we must check if some subset of k points exists such that every pair has Manhattan distance at least d.
- Converting each point to its “perimeter coordinate” (i.e. the distance along the boundary from a fixed starting corner) allows us to “order” them; however, note that the Manhattan distance between arbitrary boundary points is computed from their coordinates – so while the ordering helps iterate through candidates, distance checks use the actual Manhattan metric.
- A greedy selection procedure (with a slight “rotate‐and‐try” over the circle) can be used as a feasibility check within a binary search over possible d.
Space and Time Complexity
Time Complexity: O(log(maxDistance) * n² * k) in the worst case, where maxDistance is 2*side, n is the number of points and k ≤ 25. In practice the constant factors are small and n is at most 15×10³. Space Complexity: O(n) (we store an extended list of 2n points for handling the cyclic wrap-around).
Solution
We solve the problem by binary searching on the possible minimum Manhattan distance d. The maximum possible Manhattan distance between any two boundary points is 2 * side (e.g. from (0,0) to (side,side)) so our search space is [0, 2 * side]. For each candidate d we use a feasibility check: can we pick k points (using a greedy procedure) so that every newly picked point is at least d Manhattan distance away from every previously picked one?
Because the points are on the boundary we first assign each point a “perimeter coordinate” (pos) that represents its distance traveling clockwise around the square starting at (0,0). The mapping is as follows:
- If y == 0 (bottom edge): pos = x.
- Else if x == side (right edge): pos = side + y.
- Else if y == side (top edge): pos = 2 * side + (side - x).
- Else (x == 0, left edge): pos = 3 * side + (side - y).
Sort the points by pos. Because the boundary is cyclic, we “extend” the list by appending each point again with pos shifted by 4 * side (the total perimeter). Then for each possible starting point (from the original sorted list) we try to greedily pick points (by going through the extended list until the next point would be more than one full circle ahead). For each candidate, we include a point only if its Manhattan distance (computed directly from the (x,y) coordinates) from all previously selected points is at least d. If we can select k such points then candidate d is feasible. Based on the feasibility, we adjust our binary search.
The trickiest part is to correctly handle the cyclic order and perform the distance check among all chosen points.
Code Solutions
Below are sample solutions in Python, JavaScript, C++ and Java. Each solution is written with line‐by‐line comments.