[leetcode] 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.
https://oj.leetcode.com/problems/max-points-on-a-line/
思路:以每一个点位轴点,计算其他点的斜率,如果斜率相同则共线,用hashmap记录共线点数,不断更新最大值。
注意:有重复点需要处理,尤其是所有点都是重复点的情况需要特殊处理。
import java.util.HashMap; import java.util.Map; /** * http://blog.csdn.net/xhu_eternalcc/article/details/24556553 * http://www.cnblogs.com/TenosDoIt/p/3444086.html * @author jd * */ public class Solution { public int maxPoints(Point[] points) { if (points == null) return 0; int n = points.length; if (n <= 2) return n; Map<Double, Integer> map = new HashMap<Double, Integer>(); int maxN = 0; for (int i = 0; i < points.length; i++) { map.clear(); Point cur = points[i]; int duplicates = 1; boolean notAllDup = false; for (int j = 0; j < points.length; j++) { if (j == i) continue; if (points[i].x == points[j].x && points[i].y == points[j].y) { duplicates++; } else { notAllDup = true; Double slope = slope(cur, points[j]); if (map.get(slope) == null) { map.put(slope, 1); } else { map.put(slope, map.get(slope) + 1); } } } if (!notAllDup) { maxN = Math.max(maxN, duplicates); } for (Double key : map.keySet()) { maxN = Math.max(maxN, map.get(key) + duplicates); } } return maxN; } private double slope(Point cur, Point p) { int x1 = cur.x; int y1 = cur.y; int x2 = p.x; int y2 = p.y; if (x1 == x2 && y1 == y2) { return -Double.MAX_VALUE; } else if (x1 == x2) return Double.MAX_VALUE; else if (y1 == y2) return 0; else return 1.0 * (y2 - y1) / (x2 - x1); } public static void main(String[] args) { Point[] points = null; // 3 points = new Point[] { new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(9, 10), new Point(10, 9) }; System.out.println(new Solution().maxPoints(points)); // 5 points = new Point[] { new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(10, 10), new Point(9, 9) }; System.out.println(new Solution().maxPoints(points)); // 3 points = new Point[] { new Point(1, 1), new Point(0, 0), new Point(1, 1) }; System.out.println(new Solution().maxPoints(points)); // 3 points = new Point[] { new Point(1, 1), new Point(1, 1), new Point(1, 1) }; System.out.println(new Solution().maxPoints(points)); // 3 points = new Point[] { new Point(1, 1), new Point(1, 1), new Point(1, 0) }; System.out.println(new Solution().maxPoints(points)); // 1 points = new Point[] { new Point(1, 1) }; System.out.println(new Solution().maxPoints(points)); // 2 points = new Point[] { new Point(1, 1), new Point(1, 1) }; System.out.println(new Solution().maxPoints(points)); // 2 points = new Point[] { new Point(0, 0), new Point(1, 1), new Point(1, -1) }; System.out.println(new Solution().maxPoints(points)); } }
第二遍记录:
对于求slope,注意斜率无限大的情况和两个点重合的情况。
统计点时,注意与当前点的重合点的统计,以及所有点都是重合点的特殊情况。
第三遍记录:
重新写了一边,对于每个节点依次统计跟其他节点的斜率数, 注意跟当前节点重合的点要分开统计。
import java.util.HashMap; public class Solution { public int maxPoints(Point[] points) { if (points == null) return 0; if (points.length <= 2) return points.length; int max = 2; // at least 3 points now for (int i = 0; i < points.length; i++) { Point cur = points[i]; HashMap<Double, Integer> map = new HashMap<Double, Integer>(); int duplicates = 1; int curMax = 0; for (int j = 0; j < points.length; j++) { if (i == j) continue; if (cur.x == points[j].x && cur.y == points[j].y) { duplicates++; } else { double curSlope = slope(cur, points[j]); if (map.containsKey(curSlope)) { map.put(curSlope, map.get(curSlope) + 1); } else { map.put(curSlope, 1); } } } for (Double each : map.keySet()) { curMax = Math.max(curMax, map.get(each)); } max = Math.max(max, duplicates + curMax); } return max; } private double slope(Point a, Point b) { int x1 = a.x; int y1 = a.y; int x2 = b.x; int y2 = b.y; if (x1 == x2 && y1 == y2) { return Integer.MIN_VALUE; } else if (y1 == y2) { return 0; } else if (x1 == x2) { return Integer.MAX_VALUE; } else { return 1.0 * (y1 - y2) / (x1 - x2); } } public static void main(String[] args) { Point[] points = null; // 3 points = new Point[] { new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(9, 10), new Point(10, 9) }; System.out.println(new Solution().maxPoints(points)); // 5 points = new Point[] { new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(10, 10), new Point(9, 9) }; System.out.println(new Solution().maxPoints(points)); // 3 points = new Point[] { new Point(1, 1), new Point(0, 0), new Point(1, 1) }; System.out.println(new Solution().maxPoints(points)); // 3 points = new Point[] { new Point(1, 1), new Point(1, 1), new Point(1, 1) }; System.out.println(new Solution().maxPoints(points)); // 3 points = new Point[] { new Point(1, 1), new Point(1, 1), new Point(1, 0) }; System.out.println(new Solution().maxPoints(points)); // 1 points = new Point[] { new Point(1, 1) }; System.out.println(new Solution().maxPoints(points)); // 2 points = new Point[] { new Point(1, 1), new Point(1, 1) }; System.out.println(new Solution().maxPoints(points)); // 2 points = new Point[] { new Point(0, 0), new Point(1, 1), new Point(1, -1) }; System.out.println(new Solution().maxPoints(points)); } } class Point { int x; int y; public Point(int x, int y) { this.x = x; this.y = y; } }
参考: