直线上最多的点数问题
直线上最多的点数问题
作者:Grey
原文地址:
题目描述
LeetCode 149. Max Points on a Line
思路
共线的点,有如下可能
第一种可能:点在同一条水平线上,即纵坐标的一样。
第二种可能:点在同一个竖直线上,即横坐标一样。
第三种可能:点连成的线共斜率,即斜率一致。
三种可能分别如下图
共水平线,共竖线的值单独统计,针对共斜率的线,我们设计如下结构来存
Map<Integer,Map<Integer,Integer>> map = new HashMap<>();
map
通过如下方式来存斜率,例如:
Map<Integer,Integer> m = new HashMap<>();
m.put(3,30);
map.put(4,m);
表示:斜率为3/4
的点有30
个。
再如:
Map<Integer,Integer> m = new HashMap<>();
m.put(7,10);
map.put(5,m);
表示:斜率为7/5
的点有10
个。
假设两个点的坐标为(x1,y1)
和(x2,y2)
,那么斜率tan = (y1-y2)/(x1-x2)
,由于要用分数来表示,所以要化简,即先求x2-x1
和y2-y1
的最大公约数(辗转相除法)。
private static int gcd(int m, int n) {
return n == 0 ? m : gcd(n, m % n);
}
完整代码如下:
public static int maxPoints(int[][] points) {
if (points == null || points.length == 0) {
return 0;
}
if (points.length == 1) {
return 1;
}
int max = 1;
// map形如(3,(4,10)) 表示:斜率为3/4的点有10个
Map<Integer, Map<Integer, Integer>> map = new HashMap<>();
for (int i = 0; i < points.length; i++) {
map.clear();
int sameY = 1;
int sameX = 1;
int sameSlope = 1;
int x1 = points[i][0];
int y1 = points[i][1];
for (int j = i + 1; j < points.length; j++) {
int x2 = points[j][0];
int y2 = points[j][1];
if (x2 == x1) {
sameX++;
} else if (y2 == y1) {
sameY++;
} else {
int rangeY = y2 - y1;
int rangeX = x2 - x1;
int z = gcd(rangeX, rangeY);
rangeY = rangeY / z;
rangeX = rangeX / z;
if (map.containsKey(rangeY)) {
Map<Integer, Integer> m = map.get(rangeY);
if (m.containsKey(rangeX)) {
m.put(rangeX, m.get(rangeX) + 1);
map.put(rangeY, m);
} else {
m.put(rangeX, 2);
map.put(rangeY, m);
}
} else {
Map<Integer, Integer> m = new HashMap<>();
m.put(rangeX, 2);
map.put(rangeY, m);
}
sameSlope = Math.max(map.get(rangeY).get(rangeX), sameSlope);
}
max = Math.max(max, Math.max(Math.max(sameX, sameY), sameSlope));
}
}
return max;
}
private static int gcd(int m, int n) {
return n == 0 ? m : gcd(n, m % n);
}
更多
本文来自博客园,作者:Grey Zeng,转载请注明原文链接:https://www.cnblogs.com/greyzeng/p/16464473.html