Problem Description
Given an array of unique points on the X-Y plane, determine the minimum number of straight lines required such that every point is intersected (or covered) by at least one of these lines. Each line may cover more than two points if they are collinear.
Key Insights
- The number of points is small (up to 10), which permits a solution using bitmask dynamic programming (DP) to explore all subsets.
- Two points are always collinear; the challenge is to exploit the fact that a line defined by two points might cover additional points.
- Precomputing, for every pair of points, a bitmask representing all points on the same line helps reduce repeated computations.
- Use recursion with state represented as a bitmask to cover the remaining points with the fewest lines.
- For each DP state, pick an uncovered point and try to cover as many additional points as possible by drawing a line through it and another uncovered point.
Space and Time Complexity
Time Complexity: O(2^n * n^2) where n is the number of points (since n is at most 10, this is acceptable).
Space Complexity: O(2^n) for the DP memoization.
Solution
The solution uses a bitmask DP approach where each bit in the mask represents whether a point has been covered by a line. Initially, no points are covered (mask=0). We pick the first uncovered point and try pairing it with every other uncovered point to form a line. For each pair, we compute a bitmask of all points that lie on the line defined by these two points. Then we recursively solve for the new state after covering those points.
Important steps include:
- Checking collinearity using the cross product method.
- Precomputing the "line mask" for each pair of points.
- Using recursion (or iterative DP) with memoization to decide the optimal set of lines that covers all points.
Code Solutions
Below are the solutions in Python, JavaScript, C++, and Java.