
Input: points =[[0,1],[2,3],[4,5],[4,3]]Output: 2Explanation: The minimum number of straight lines needed is two. One possible solution is to add:- One line connecting the point at(0,1) to the point at(4,5).- Another line connecting the point at(2,3) to the point at(4,3).
Example 2:
1
2
3
4
5

Input: points =[[0,2],[-2,-2],[1,4]]Output: 1Explanation: The minimum number of straight lines needed is one. The only solution is to add:- One line connecting the point at(-2,-2) to the point at(1,4).
For each subset of points, we can cover them with a single line if they are collinear. Use DP with bitmask: for each mask, try all possible lines, and recursively cover the rest. The answer is the minimum number of lines needed to cover all points.
classSolution:
defminLines(self, points: list[list[int]]) -> int:
n = len(points)
col = [[0]*n for _ in range(n)]
for i in range(n):
for j in range(n):
mask =0for k in range(n):
x1, y1 = points[i]
x2, y2 = points[j]
x3, y3 = points[k]
if (x2-x1)*(y3-y1) == (y2-y1)*(x3-x1):
mask |=1<<k
col[i][j] = mask
dp = [n]*(1<<n)
dp[0] =0for mask in range(1<<n):
if dp[mask] == n: continue first =0while first < n andnot (mask & (1<<first)): first +=1if first == n: continuefor j in range(n):
new_mask = mask | col[first][j]
dp[new_mask] = min(dp[new_mask], dp[mask]+1)
return dp[(1<<n)-1]
impl Solution {
pubfnmin_lines(points: Vec<Vec<i32>>) -> i32 {
let n = points.len();
letmut col =vec![vec![0; n]; n];
for i in0..n {
for j in0..n {
letmut mask =0;
for k in0..n {
let (x1, y1) = (points[i][0], points[i][1]);
let (x2, y2) = (points[j][0], points[j][1]);
let (x3, y3) = (points[k][0], points[k][1]);
if (x2-x1)*(y3-y1) == (y2-y1)*(x3-x1) { mask |=1<<k; }
}
col[i][j] = mask;
}
}
letmut dp =vec![n; 1<<n];
dp[0] =0;
for mask in0..(1<<n) {
if dp[mask] == n { continue; }
letmut first =0;
while first < n && (mask & (1<<first)) ==0 { first +=1; }
if first == n { continue; }
for j in0..n {
let new_mask = mask | col[first][j];
dp[new_mask] = dp[new_mask].min(dp[mask]+1);
}
}
dp[(1<<n)-1]
}
}