• [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;
        }
    
    }

    参考:

    http://blog.csdn.net/xhu_eternalcc/article/details/24556553

    http://www.cnblogs.com/TenosDoIt/p/3444086.html

  • 相关阅读:
    P4097 [HEOI2013]Segment(李超线段树模板)
    P2155 [SDOI2008]沙拉公主的困惑
    BZOJ3675 [Apio2014]序列分割[斜率优化dp]
    hdu4261 Estimation[暴力dp+对顶堆]
    poj2374 Fence Obstacle Course[线段树+DP]
    poj1463 Strategic game[树形DP]
    CH5E02 [IOI1999]花店橱窗[暴力dp]
    CH5E01[NOIP2010] 乌龟棋[暴力]
    CH5702 Count The Repetitions[倍增dp]
    P1081 [NOIP2012]开车旅行[倍增]
  • 原文地址:https://www.cnblogs.com/jdflyfly/p/3830475.html
Copyright © 2020-2023  润新知