题目
给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/max-points-on-a-line
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
就是很简单的存储斜率和截距,但因为会有各种特殊情况,所以提交了好多遍…… 最最最最重要的是:别用double存储,会丢失精度 ,用字符串!
下面代码是这位作者提供的。
class Solution {
public int maxPoints(int[][] points) {
if (points.length < 3) return points.length; // none\one\two points
int maxCount = 1;
for (int i = 0; i < points.length - 1; i++)
maxCount = Math.max(computeMaxPointsThrougthIndexPoint(points, i), maxCount);
return maxCount;
}
private int horizontalLines; // 与指定点i在同一水平线点数
private Map<String, Integer> linePointsMap = new HashMap<>(); // 与指定点i在同一斜线点数
private int count; // 指定点i在同一直线最大点数
private int duplicates; // 与指定点i重复的点数
public int computeMaxPointsThrougthIndexPoint(int[][] points, int i) {
clearStatisticData();
for (int j = i + 1; j < points.length; j++)
statistic(points, i, j);
return this.count + this.duplicates;
}
private void clearStatisticData() {
this.linePointsMap.clear(); // 清空,重新统计
this.horizontalLines = 1; // 水平线
this.count = 1; // 当前在一条线上的点,初始化为1,自己
this.duplicates = 0; // 重复点统计
}
private void statistic(int[][] points, int i, int j) {
int x1 = points[i][0], y1 = points[i][1];
int x2 = points[j][0], y2 = points[j][1];
if ((x1 == x2) && (y1 == y2)) duplicates++; // 重复点统计
else if (y1 == y2) { // 水平线
this.horizontalLines += 1;
this.count = Math.max(horizontalLines, this.count);
}
else { // 斜线统计
String slope = buildSlope(x1 - x2, y1 - y2);
this.linePointsMap.put(slope, this.linePointsMap.getOrDefault(slope, 1) + 1);
this.count = Math.max(this.linePointsMap.get(slope), count);
}
}
private String buildSlope(int p, int q) {
int gcd = computeGcd(p, q);
return p / gcd + "_" + q / gcd;
}
private int computeGcd(int p, int q) {
if (q == 0) return p;
int r = p % q;
return computeGcd(q, r);
}
}