Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
最简单直接方法就是把某一点固定,然后寻找所有到剩余点的斜率,两次循环之后就能得到题目所要求。
直线我们很快想到斜率来表示,利用斜率最需要注意斜率无穷大的情况,需要拿出来单独进行考虑。其实我觉得这个题目有一些问题就是:我们使用Double 来表示斜率,但是小数无法进行精确比较!!但是LeetCode上测试案例没有这么极端,不考虑这个问题也能AC。
package Max_Points_on_a_Line;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class Solution {
public static void main(String[] args) {
Solution s = new Solution();
Point arr[] = { new Point(-8, -582),
new Point(-9, -651), new Point(9, 591) };
System.out.println(s.maxPoints(arr));
}
public int maxPoints(Point[] points) {
if (points.length < 2) {
return points.length;
}
int maxNum = 0;
Map<Double, Integer> mp = new TreeMap<>();
mp.clear();
for (int i = 0; i < points.length; i++) {
//Important : 每次需要进行重置!!!
int duplicated = 1;
mp.clear();
// 斜率为无穷大的情况
mp.put(Double.MAX_VALUE, 0);
for (int j = 0; j < points.length; j++) {
if (i == j)
continue;
//记录有多少重复的点。
if ((points[i].x == points[j].x)
&& (points[i].y == points[j].y)) {
duplicated++;
continue;
}
double k = points[i].x == points[j].x ? Double.MAX_VALUE
: (double) (points[i].y - points[j].y)/((points[i].x - points[j].x)) ;
if (!mp.containsKey(k)) {
mp.put(k, 1);
} else {
mp.put(k, mp.get(k) + 1);
}
}
Set<Map.Entry<Double, Integer>> set = mp.entrySet();
Iterator<Map.Entry<Double, Integer>> it = set.iterator();
for (; it.hasNext();) {
Map.Entry<Double, Integer> entry = it.next();
if (entry.getValue()+ duplicated > maxNum) {
maxNum = entry.getValue() + duplicated;
}
}
}
return maxNum;
}
}
class Point {
int x;
int y;
Point() {
x = 0;
y = 0;
}
Point(int a, int b) {
x = a;
y = b;
}
}
这里需要注意几点:
1. 计算斜率公式:(double) (points[i].y - points[j].y)/((points[i].x - points[j].x)) 一定不能为 (double) ( (points[i].y - points[j].y)/((points[i].x - points[j].x))) 第二个式子为两个整数相除结果为整数然后再强制转型,而第一个就是先把第一个数转成double 然后再进行除法。
2. 注意
if (points.length < 2) {
return points.length;
}
测试案例中必然将包含数组为空的情况。
3. 我个人觉得这个最好方法还是不用斜率去判断是否在一条直线上,而是 利用公式 y1/x1 ?== y2/x2 把除法变成乘法来判断,这样就避免浮点数相等判断。