leetcode 第149题 Max Points on a Line

题目要求:

给定2D平面上的n个点,找出位于同一条直线上的最大点数。

解决思路

这个问题的一种方案是考虑两点之间斜率,把斜率相同的点放置在一个表中,再找到包含最多点的斜率。这个其中有两点需要关注,一个是点坐标的取值范围,一个是涉及斜率计算的问题。
我的想法是对于每一个点,分别计算在它之后的所有不同点的斜率,并且用一个Map集合存起来,对于这个点,找出斜率最大的那个。考虑它的正确性,我们可以假设一种极端情况,即给定所有的点都在一条直线上,那么第一个点中肯定已经可以计算所要的结果,其他的点虽然能正常运行,但是同一个斜率得到结果肯定比第一个少。
这里还要指出的是,斜率计算的问题,当横坐标相同时,用Integer.MAX_VALUE表示。考虑到Double运算可能会出现精度溢出情况,采用了BigDecimal类来计算精确结果。

java代码

/**
 * Definition for a point.
 * class Point {
 *     int x;
 *     int y;
 *     Point() { x = 0; y = 0; }
 *     Point(int a, int b) { x = a; y = b; }
 * }
 */
class Solution {
    public  int maxPoints(Point[] points) {
        int res = 1;
        if(points.length==0) return 0;

        for(int i =0;i<points.length;i++){
            HashMap<Double,Integer> hm = new HashMap<>();
            hm.put((double) Integer.MIN_VALUE,1);//当points数组不空时,直线上必有一点

            int de = 0;
            for(int j=i+1;j<points.length;j++){

                if((points[i].y==points[j].y)&&(points[i].x==points[j].x)){ 
                    de++;
                }else{
                    double tt = dis(points[i],points[j]);
                    if(hm.containsKey(tt))
                        hm.put(tt,hm.get(tt)+1);
                    else
                        hm.put(tt,2);               
                }   
            }


            for(int re:hm.values())                 
                res  = Math.max(res, de+re);
        }

        return res;
    }

    public static double dis(Point p1, Point p2) {

        if((p1.x-p2.x)==0) 
            return (double)Integer.MAX_VALUE;
        if(p1.y==p2.y) 
            return 0;
        java.math.BigDecimal bd1 = new java.math.BigDecimal(Double.toString(p1.y-p2.y)); 
        java.math.BigDecimal bd2 = new java.math.BigDecimal(Double.toString(p1.x-p2.x)); 
        return bd1.divide  
               (bd2,16,java.math.BigDecimal.ROUND_HALF_UP).doubleValue(); 
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值