算法-训练

1、直线上最多的点数

1.1、题目

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

1.2、测试样例

1.3、约束

1.4、题解

由于利用两个点确定一条直线有精度的限制,下面两种方法是将求斜率的方法转化为乘法进行处理

方法1

利用三点来确定一条直线的斜率

这样就可以解决掉斜率为小数的精度问题。

方法2

利用Hash表进行记录每次遍历的斜率找到,共线的最多点数,而这次是利用消除最大公因数来解决精度问题。

朴素的方法

public class Max_Point_on_a_line {
    public int maxPoints(int[][] points) {
        int n=points.length;
        int res=0;
        for(int i=0;i<n;i++){
            int p[]=points[i];
            for(int j=i+1;j<n;j++){
                int cnt=2;
                int q[]=points[j];
                for(int k=j+1;k<n;k++){
                    int m[]=points[k];
                    int s1=(p[1]-q[1])*(q[0]-m[0]);
                    int s2=(m[1]-q[1])*(p[0]-q[0]);
                    if(s1==s2){
                        cnt++;
                    }

                }
                res=Math.max(res,cnt);
            }
        }
        return res;
    }
}

朴素的方法+哈希表

class Solution {
  public int maxPoints(int[][] points) {
        if(points.length==1){
            return 1;
        }
        int n=points.length;
        int res=0;
        for(int i=0;i<n;i++){
            Map<String,Integer> map=new HashMap<>();
            for(int j=i+1;j<n;j++){
                int x1=points[i][0];
                int y1=points[i][1];
                int x2=points[j][0];
                int y2=points[j][1];
                int a=(x2-x1);
                int b=(y2-y1);
                int k=gcd(a,b);
                String key=(a/k)+"_"+(b/k);
                System.out.println(key);
                map.put(key,map.getOrDefault(key,0)+1);
                System.out.println(map.get(key));
                res=Math.max(res,map.get(key)+1);
            }
        }
        return res;
    }
    int gcd(int a,int b){
        if(b==0){
            return a;
        }
        return gcd(b,a%b);
    }
}
  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值