「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
描述
给定一个二维平面及平面上的 N 个点列表Points,其中第i个点的坐标为Points[i]=[Xi,Yi]。请找出一条直线,其通过的点的数目最多。
设穿过最多点的直线所穿过的全部点编号从小到大排序的列表为S,你仅需返回[S[0],S[1]]作为答案,若有多条直线穿过了相同数量的点,则选择S[0]值较小的直线返回,S[0]相同则选择S[1]值较小的直线返回。
- 示例 1:
输入: [[0,0],[1,1],[1,0],[2,0]]
输出: [0,2]
解释: 所求直线穿过的3个点的编号为[0,2,3]
- 提示:
2 <= len(Points) <= 300len(Points[i]) = 2
解析
解答本题的思路比较笨重,还没有想到其他好的方式
- 两个点为一条直线, 遍历
- 组成的结果放在一个int[]里面
- 组合好了之后选一个最大的, 最大的里面选一个S[0,1]最小的
class Solution {
public int[] bestLine(int[][] points) {
// 思路:
//
int[] remove = new int[points.length];
int[][] max = new int[points.length][points.length];
int maxNum = -1;
for (int i = 0; i < points.length - 1; i ++) {
for (int j = i + 1; j < points.length; j ++) {
// 如果之前记录过这个点就跳过, 这个不应该, 如果这两个点在其他的线上
// if (remove[j] == remove) {
// continue;
// }
// 计算直线公式
double a, b, c;
if (points[i][0] == points[j][0]) {
// x = c 类型
a = 1;
b = 0;
c = - points[i][0];
} else {
// 运算要转double
a = ((double)(points[i][1] - points[j][1])) / (points[i][0] - points[j][0]);
c = points[i][1] - a * points[i][0];
b = -1;
}
// 遍历以后的每一个节点, 看是否符合
int num = 2;
for (int k = j + 1; k < points.length; k ++) {
// 加一个误差范围吧
if (-0.0001 < a * points[k][0] + b * points[k][1] + c && 0.0001 > a * points[k][0] + b * points[k][1] + c ) {
num ++;
// 记下这个点所在的线段
remove[k] = i + 1;
}
}
// 记录
max[i][j] = num;
maxNum = Math.max(num, maxNum);
}
}
// 找到那个最大的
for (int i = 0; i < points.length-1; i ++) {
for (int j = i; j < points.length-1; j ++) {
if (max[i][j] == maxNum) {
return new int[]{i, j};
}
}
}
return new int[]{-1, -1};
}
}
运行结果:
执行结果:通过
执行用时:
内存消耗: