Max Points on a Line (H)
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
Example 1:
Input: [[1,1],[2,2],[3,3]]
Output: 3
Explanation:
^
|
| o
| o
| o
+------------->
0 1 2 3 4
Example 2:
Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
Output: 4
Explanation:
^
|
| o
| o o
| o
| o o
+------------------->
0 1 2 3 4 5 6
NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.
题意
给定n个二维点,返回最大共线点数目。
思路
固定一个点,以该点为基准,计算其他所有点到该点的斜率,斜率相同则说明共线,斜率信息用HashMap记录。更换基准点重复上述步骤。有以下几点要注意:
- 因为本题允许相同点的存在,所以要统计每一个基准点相同点的个数,之后要加到共线点数结果中;如果最后HashMap没有记录,说明只存在相同点;
- 因为double的精度不够,在部分case会出现判断错误(虽然用斜率的倒数作为key可以AC),所以HashMap使用String来作为key,具体方法为将斜率用分数形式表示,约分后转化为字符串作为key。
代码实现
class Solution {
public int maxPoints(int[][] points) {
if (points.length <= 2) {
return points.length;
}
int maxCount = 0;
Map<String, Integer> slopes = new HashMap<>();
for (int i = 0; i < points.length; i++) {
int baseX = points[i][0], baseY = points[i][1];
int sameCount = 1; // 统计重复基准点个数,初始为1指自身
int maxTemp = 0; // 记录当前基准点得到的最大共线点数
slopes.clear(); // 注意每次更换基准点都要清空HashMap
for (int j = i + 1; j < points.length; j++) {
int curX = points[j][0], curY = points[j][1];
// 重复基准点处理
if (curX == baseX && curY == baseY) {
sameCount++;
continue;
}
// 找到最大公约数,并进行约分,并将斜率转化为分数形式
int gcd = gcd(curX - baseX, curY - baseY);
String slope = (curX - baseX) / gcd + "/" + (curY - baseY) / gcd;
// 更新HashMap以及当前最大共线点数
slopes.put(slope, 1 + (slopes.containsKey(slope) ? slopes.get(slope) : 0));
maxTemp = Math.max(maxTemp, slopes.get(slope));
}
maxCount = Math.max(maxCount, maxTemp + sameCount);
}
return maxCount;
}
private int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
}
本文介绍了一种解决二维平面上寻找最多共线点数目的算法。通过固定一个点并计算其余各点相对该点的斜率,利用哈希表存储斜率信息,最终找出最大的共线点数目。
2018

被折叠的 条评论
为什么被折叠?



