zoukankan      html  css  js  c++  java
  • [LeetCode 149] 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.
     
    Example 1:
    Input: [[1,1],[2,2],[3,3]]
    Output: 3
    Explanation:
    ^
    |
    |        o
    |     o
    |  o  
    +------------->
    0  1  2  3  4
    
    Example 2:
    Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
    Output: 4
    Explanation:
    ^
    |
    |  o
    |     o        o
    |        o
    |  o        o
    +------------------->
    0  1  2  3  4  5  6







     
     
    The O(N^2) solution is fairly straightforward, the tricky parts are how to accurately track slope and handling corner cases of horizontal and vertical lines.
     
    1. sort all points first by x then by y.
    2. count up all duplicated points P, then do a linear check to find the max number of points that can be on the same line with P. The answer is the max of all/
     
    Give a point p, check all other different points to get the max number of points that can be on the same line with p.  If we have a point p and a slope, we have one unique line passing p. We can then use a hashmap to track different slopes and the groups of points that are on that line of slope. The tricky part here is that we can not use double type to track slope due to the precision errors. We should use GCD to do this. We should also consider the horizontal and vertical lines corner cases separately. That's it:)
       
     
    class Solution {
        public int maxPoints(int[][] points) {
            if(points.length <= 1) return points.length;
            Arrays.sort(points, (p1, p2) -> {
                if(p1[0] != p2[0]) return p1[0] - p2[0];
                return p1[1] - p2[1];
            });
            int ans = 0, cnt = 1;
            for(int i = 1; i < points.length; i++) {
                if(points[i][0] == points[i - 1][0] && points[i][1] == points[i - 1][1]) {
                    cnt++;
                }
                else {
                    ans = Math.max(ans, maxWithPointK(points, i - 1) + cnt);
                    cnt = 1;
                }
            }
            ans = Math.max(ans, maxWithPointK(points, points.length - 1) + cnt); 
            return ans;
        }
        //gcd(dx, dy), if dy == 0, return dx
        private int gcd(int a, int b) {
            if(b == 0) {
                return a;
            }
            return gcd(b, a % b);
        }
        //O(N) time
        private int maxWithPointK(int[][] points, int k) {
            Map<List<Integer>, List<Integer>> map = new HashMap<>();
            for(int i = 0; i < points.length; i++) {
                int dx = points[i][0] - points[k][0];
                int dy = points[i][1] - points[k][1];
                //skip duplicated points 
                if(dx == 0 && dy == 0) continue;
                //slope = dy / dx
                List<Integer> slope = new ArrayList<>();
                int v1 = 0, v2 = 0;
                if(dx == 0) {
                    v1 = 0;
                    v2 = 0;
                }
                else if(dy == 0){
                    v1 = points[k][0];
                    v2 = 0;              
                }
                else {
                    int gcd = gcd(Math.abs(dx), Math.abs(dy));
                    v1 = Math.abs(dx) / gcd;
                    v2 = Math.abs(dy) / gcd;
                    if(dx > 0 && dy < 0 || dx < 0 && dy > 0) {
                        v1 *= -1;
                    }                    
                }
                slope.add(v1);
                slope.add(v2);
                map.putIfAbsent(slope, new ArrayList<>());
                List<Integer> p = map.get(slope);
                p.add(i);
            }
            int maxCnt = 0;
            for(Map.Entry<List<Integer>, List<Integer>> e : map.entrySet()) {
                maxCnt = Math.max(maxCnt, e.getValue().size());
            }
            return maxCnt;
        }
    }
  • 相关阅读:
    System.currentTimeMillis();
    Spark Core源代码分析: Spark任务模型
    CocoaPods on Xcode 6 and Yosemite
    leetcode第一刷_Binary Tree Inorder Traversal
    struts2讲义----建立一个struts2工程
    Java实现 蓝桥杯VIP 算法提高 班级排名
    Java实现 蓝桥杯VIP 算法提高 种树
    Java实现 蓝桥杯VIP 算法提高 种树
    Java实现 蓝桥杯VIP 算法提高 种树
    Java实现 蓝桥杯VIP 算法提高 种树
  • 原文地址:https://www.cnblogs.com/lz87/p/7494078.html
Copyright © 2011-2022 走看看