Max Points on a Line
问题描述
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
解决思路
1. 定义Line类
{slope; intercept; isVertical; isHorizontal}
定义hashcode(), equals()方法
2. 遍历每两两的点,记录下数目最多的Line;
3. 遍历所有的点,记录下在该Line上的点的数目,即为共线的最大数目;
注意:点集中有可能有重合的点。
程序
class Line { static double epsilo = 0.00001; double slope; double intercept; boolean isVertical; boolean isHorizontal; public Line(double x1, double y1, double x2, double y2) { if (isEquals(x1, x2)) { isVertical = true; intercept = x1; } else if (isEquals(y1, y2)) { isHorizontal = true; intercept = y1; } else { slope = (y1 - y2) / (x1 - x2); intercept = x1 - y1 / slope; } } public static boolean isEquals(double d1, double d2) { return Math.abs(d1 - d2) < epsilo; } @Override public boolean equals(Object obj) { if (!(obj instanceof Line)) { return false; } Line line = (Line) obj; if (isEquals(line.slope, this.slope) && isEquals(line.intercept, this.intercept) && line.isVertical == this.isVertical && line.isHorizontal == this.isHorizontal) { return true; } return false; } @Override public int hashCode() { return (int) (slope * 1000) | (int) (intercept * 1000); } } public class Solution { public int maxPoints(Point[] points) { if (points == null) { return 0; } if (points.length <= 2) { return points.length; } HashMap<Line, Integer> map = new HashMap<Line, Integer>(); for (int i = 0; i < points.length - 1; i++) { for (int j = i + 1; j < points.length; j++) { Point p1 = points[i]; Point p2 = points[j]; Line line = new Line(p1.x, p1.y, p2.x, p2.y); if (map.containsKey(line)) { map.put(line, map.get(line) + 1); } else { map.put(line, 1); } } } int max = 0; Line maxLine = null; for (Line l : map.keySet()) { if (map.get(l) > max) { max = map.get(l); maxLine = l; } } if (maxLine == null) { return -1; } int cnt = 0; if (maxLine.isVertical) { for (Point point : points) { if (Line.isEquals(point.x, maxLine.intercept)) { ++cnt; } } } else if (maxLine.isHorizontal) { for (Point point : points) { if (Line.isEquals(point.y, maxLine.intercept)) { ++cnt; } } } else { for (Point point : points) { if (Line.isEquals(point.y, maxLine.slope * (point.x - maxLine.intercept))) { ++cnt; } } } return cnt; } }