Max Points on a Line
Hard
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
题意
给定第一象限的若干点,求共线的点的最大数目
思路
一条直线可以由一个点和一个斜率确定。遍历所有点(x0, y0),对于每个(x0, y0),用一个键为斜率k(斜率用Pair<Integer, Integer>表示),值为与(x0, y0)连线的斜率为k的点的数量的HashMap记录共线点的个数,从而对于每个(x0, y0)求得包含(x0, y0)的共线点的最大数目。
有两个坑点:
- 如果直接用一个double表示斜率,由于精度问题会产生误判,因此用自建的整数对类Pair<Integer, Integer>表示斜率,使得Pair中的两个整数的互素。因此通过整数对(a, b)创建Pair对象时要先通过辗转相除法求得(a, b)的最大公因子,将(a, b)约去最大公因子。另外,由于Pair会作为HashMap的键,因此要重写Pair的hashCode()和equals(Object o)方法
- 题目中可能出现重合点,重合点要单独处理
代码
class Solution {
class Pair {
int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
return 31*x + y;
}
@Override
public boolean equals(Object others) {
return ((Pair)others).x == x && ((Pair)others).y == y;
}
}
public int maxPoints(int[][] points) {
int n = points.length, i = 0, j = 0, ans = 0, cur = 0, overlap = 0;
HashMap<Pair, Integer> map = new HashMap<Pair, Integer>();
if (n <= 1) {
return n;
}
for (i=0; i<n; i++) {
cur = 0;
overlap = 0;
map.clear();
for (j=0; j<n; j++) {
int x = points[j][0] - points[i][0], y = points[j][1] - points[i][1];
if (x == 0 && y == 0) {
++overlap;
} else {
if (x == 0) {
y = 1;
} else if (y == 0) {
x = 1;
} else {
int gcd = doGCD(x, y);
x /= gcd;
y /= gcd;
}
Pair pair = new Pair(x, y);
if (!map.containsKey(pair)) {
map.put(pair, 1);
} else {
map.put(pair, map.get(pair) + 1);
}
cur = map.get(pair) > cur ? map.get(pair): cur;
}
}
ans = (cur + overlap) > ans? (cur + overlap): ans;
}
return ans;
}
private int doGCD(int x, int y) {
if (y == 0) {
return x;
}
return doGCD(y, x%y);
}
}