https://leetcode.cn/problems/max-points-on-a-line/?envType=study-plan-v2&envId=top-interview-150
我们可以通过斜率 + 出发点位置来判断多个点是否位于同一条直线,遍历所有点依次选取作为出发点然后遍历其它点计算斜率,并且通过hashmap来记录斜率出现的次数,对于水平线和竖直线我们可以单独拿出来统计,最后比较得出三种情况的最大值。
java
public int maxPoints(int[][] points) {
int n = points.length;
if (n <= 2) {
return n;
}
int res = 0;
for (int i = 0; i < n; i++) {
HashMap<Double, Integer> map = new HashMap<>();
int row = 1, col = 1; // 记录水平线和竖直线
int max = 0; // 记录斜率出现次数的最大值
for (int j = i + 1; j < n; j++) {// 遍历其它点
if (points[i][0] == points[j][0]) {
col++;
continue;
}
if (points[i][1] == points[j][1]) {
row++;
continue;
}
// 斜线情况
double k = (double) (points[i][1] - points[j][1]) / (points[i][0] - points[j][0]);
if(!map.containsKey(k)) {
map.put(k, 2);
} else {
map.put(k, map.get(k) + 1);
}
max = Math.max(max, map.get(k));
}
max = Math.max(max, Math.max(row, col));
res = Math.max(res, max);
}
return res;
}
我们还可以使用向量叉积来判断是否共线,向量共线条件:dx1 * dy2 == dx2 * dy1
java
public int maxPoints(int[][] points) {
int n = points.length;
if(n <= 2) return n;
int res = 2;
// 因为points的长度比较小,三层for可以接受
for(int i = 0; i < n; i++) {
for(int j = i + 1; j < n; j++) {
// 选取两个点计算向量
int x1 = points[i][0], y1 = points[i][1];
int x2 = points[j][0], y2 = points[j][1];
int max = 2;
// 计算向量
int dx1 = x2 - x1, dy1 = y2 - y1;
// 找第三点
for(int k = j + 1; k < n; k++) {
// 计算第一点和第三点向量
int dx2 = points[k][0] - x1, dy2 = points[k][1] - y1;
// 判断之前向量是否共线
if(dx1 * dy2 == dx2 * dy1) {
// 共线则计数
max++;
res = Math.max(res, max);
}
}
}
}
return res;
}