ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LeetCode-149. 直线上最多的点数

2022-03-06 11:03:43  阅读:172  来源: 互联网

标签:x1 int 149 x2 points y1 点数 y2 LeetCode


题目来源

149. 直线上最多的点数

题目详情

给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。

示例 1:

输入: points = [[1,1],[2,2],[3,3]]
输出: 3

示例 2:

输入: points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出: 4

提示:

  • 1 <= points.length <= 300
  • points[i].length == 2
  • -104 <= xi, yi <= 104
  • points 中的所有点 互不相同

题解分析

解法一:暴力法

class Solution {
    public int maxPoints(int[][] points) {
        int n = points.length;
        // y1 = kx1 + b
        // y2 = kx2 + b
        // k = (y1-y2) / (x1-x2), b = y1 - x1 * ((y1-y2) / (x1-x2))
        
        int ans = 1;
        for(int i=0; i<n; i++){
            int x1 = points[i][0], y1= points[i][1];
            for(int j=i+1; j<n; j++){
                int x2 = points[j][0], y2= points[j][1];
                int max = 2;
                for(int k=j+1; k<n; k++){
                    int x3 = points[k][0], y3= points[k][1];
                    // 不直接比较两个斜率,而是将除法的比较转换为乘法比较
                    int temp1 = (y2-y1) * (x3-x2);
                    int temp2 = (y3-y2) * (x2-x1);
                    if(temp1 == temp2){
                        max++;
                    }
                }
                ans = Math.max(ans, max);
            }
        }
        return ans;
    }
}

解法二:HashMap优化

  1. 从解法一我们可以看到,这种方法的时间复杂度为\(O(n^3)\),那有什么方法能够减少时间复杂度呢?
  2. 对于本题而言,我们可以从如何判断两个点共线来思考。我们在方法一中是通过遍历剩下所有点来判断它是否和已有的直线共线来判断是否三点共线的。从这里,我们可以看到,我们只需要固定起始点,然后遍历剩下的点,再记录下它们与起始点的斜率,如果斜率相同的汇总在一起,表明这些点一定共线(不需要判断截距了,因为起始点是固定的,这就相当于截距固定了)。
  3. 所以,这里我们可以使用一个HashMap来存储斜率,并在里层循环中,将所有斜率相同的点进行汇总,拥有最多点的直线就是以起始点为开始的最佳直线。
  4. 此外,本题还有一个问题,那就是有可能我们计算的斜率是double型的,直接将其作为key进行存储,有可能会面临精度丢失的问题。那我们应该存储什么呢?从计算斜率的公式出发,k=(y1-y2)/(x1-x2),我们可以存储y1-y2以及x1-x2,这两个结果可以确定斜率。但是,我们也不能直接存储y1-y2以及x1-x2,因为它们之间可以存在倍数的关系,所以我们需要将y1-y2以及x1-x2除尽。
class Solution {
    public int maxPoints(int[][] points) {
        int n = points.length;
        // y1 = kx1 + b
        // y2 = kx2 + b
        // k = (y1-y2) / (x1-x2), b = y1 - x1 * ((y1-y2) / (x1-x2))
        
        int ans = 0;
        for(int i=0; i<n; i++){
            int x1 = points[i][0], y1= points[i][1];
            Map<String,Integer> map = new HashMap<>();
            int max = 0;
            for(int j=i+1; j<n; j++){
                int x2 = points[j][0], y2= points[j][1];
                int ydif = y1-y2;
                int xdif = x1-x2;
                int common = gcd(ydif, xdif);
                String key = Arrays.toString(new int[]{ydif/common, xdif/common});
                int num = map.getOrDefault(key, 0);
                map.put(key, num + 1);
                max = Math.max(max, num+1);
            }
            ans = Math.max(ans , max +1);
        }
        return ans;
    }

    private int gcd(int a, int b){
        return b == 0 ? a : gcd(b, a%b);
    }
}

标签:x1,int,149,x2,points,y1,点数,y2,LeetCode
来源: https://www.cnblogs.com/GarrettWale/p/15970990.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有