You are given an integer side, representing the edge length of a square with corners at (0, 0), (0, side), (side, 0), and (side, side) on a Cartesian plane.
You are also given a positive integer k and a 2D integer array points, where points[i] = [xi, yi] represents the coordinate of a point lying on the boundary of the square.
You need to select k elements among points such that the minimum Manhattan distance between any two points is maximized.
Return the maximum possible minimum Manhattan distance between the selected k points.
The Manhattan Distance between two cells (xi, yi) and (xj, yj) is |xi - xj| + |yi - yj|.
Β
Example 1:
Input:side = 2, points = [[0,2],[2,0],[2,2],[0,0]], k = 4
Output:2
Explanation:
Select all four points.
Example 2:
Input:side = 2, points = [[0,0],[1,2],[2,0],[2,2],[2,1]], k = 4
Output:1
Explanation:
Select the points (0, 0), (2, 0), (2, 2), and (2, 1).
Example 3:
Input:side = 2, points = [[0,0],[0,1],[0,2],[1,2],[2,0],[2,2],[2,1]], k = 5
Output:1
Explanation:
Select the points (0, 0), (0, 1), (0, 2), (1, 2), and (2, 2).
Since the problem asks to maximize the minimum distance, we can use binary search on the answer to find the optimal solution.
First, to simplify the logic, we map the 2D coordinates \((x, y)\) on the square's boundary to a 1D axis \([0, 4 \times \text{side})\). The mapping rules are as follows:
If \(x = 0\), the mapped value is \(y\);
If \(y = \text{side}\), the mapped value is \(\text{side} + x\);
If \(x = \text{side}\), the mapped value is \(3 \times \text{side} - y\);
Otherwise, the mapped value is \(4 \times \text{side} - x\).
After mapping, sort all the points to obtain the array \(\textit{nums}\). Since the points are selected on the perimeter of the square, this is essentially a circular (ring) problem.
During the binary search, for a given minimum distance \(\textit{lo}\), we use a \(\textit{check}\) function to verify its feasibility:
Iterate through each point in \(\textit{nums}\) as the starting point \(\textit{start}\).
The endpoint for selecting points is \(\textit{end} = \textit{start} + 4 \times \text{side} - \textit{lo}\), ensuring that the wrap-around distance from the last selected point back to \(\textit{start}\) is at least \(\textit{lo}\).
Then, greedily perform \(k-1\) jumps, each time using binary search to quickly locate the next point that is at least \(\textit{lo}\) away from the current position.
If it is possible to select \(k\) points within the \(\textit{end}\) limit, then the distance \(\textit{lo}\) is feasible.
The time complexity is \(O(n \log (\text{side}) \cdot n \log n)\) and the space complexity is \(O(n)\), where \(n\) is the length of the \(\textit{points}\) array.