意识到下边这点是关键:
斜率和与X轴的交点可以确定一条直线。
依据此推论,按照斜率和与X轴的交点对点进行分组,最后看哪个组中的点最多。
对于与X轴平行的直线需单独另分组。
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class Solution {
public int maxPoints(Point[] points) {
if (points.length == 1 || points.length == 2) {
return points.length;
}
Map<Double, Set<Integer>> yMap = new HashMap<Double, Set<Integer>>();//存放与X轴平行的直线,KEY:与Y轴交点坐标,VALUE:Point
//存放与x轴有交点的直线,KEY-斜率,VLUE-(KEY-与X轴交点的X坐标,VALUE-Point)
Map<Double, Map<Double, Set<Integer>>> xMap = new HashMap<Double, Map<Double, Set<Integer>>>();
for (int i = 0; i < points.length - 1; i++) {
for (int j = i + 1; j < points.length; j++) {
if (points[i].y == points[j].y) { //与X轴平行
double ykey= points[i].y;
Set<Integer> list = yMap.get(ykey);
if (list == null) {
list = new HashSet<Integer>();
yMap.put(ykey, list);
}
list.add(i);
list.add(j);
} else { //与X轴有交点
double tan;//斜率
//与X轴交点的X坐标
double xkey = points[j].x - (double) ((points[j].x - points[i].x) * points[j].y) / (double) (points[j].y - points[i].y);
if (points[j].x - points[i].x == 0) {
tan = Double.NaN;
} else {
tan = (double) (points[j].y - points[i].y) / (double) (points[j].x - points[i].x);
}
Map<Double, Set<Integer>> m = xMap.get(tan);
if (m == null) {
m = new HashMap<Double, Set<Integer>>();
xMap.put(tan, m);
}
Set<Integer> set = m.get(xkey);
if (set == null) {
set = new HashSet<Integer>();
m.put(xkey, set);
}
set.add(i);
set.add(j);
}
}
}
int max = 0;
for (Map<Double, Set<Integer>> tan : xMap.values()) {
for (Set<Integer> set : tan.values()) {
max = Math.max(max, set.size());
}
}
for (Set<Integer> set: yMap.values()) {
max = Math.max(max, set.size());
}
return max;
}
public static void main(String[] args) {
Point[] ps = new Point[] {
new Point(0,0),
new Point(1,1),
new Point(1,-1)
};
Solution s = new Solution();
int m = s.maxPoints(ps);
System.out.print(m);
}
}