leetcode:统计在同一条直线上的点的数量

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

/**
 * Definition for a point.
 * class Point {
 *     int x;
 *     int y;
 *     Point() { x = 0; y = 0; }
 *     Point(int a, int b) { x = a; y = b; }
 * }
 */
//实现思想:从每一个点出发,固定起点,计算斜率相同的次数加上起点自身就是直线上的点
public class Solution {
    public int maxPoints(Point[] points) {
        //非空判断
        if(points==null||points.length==0)
        {
            return 0;
        }
        //只有一个或两个节点 直接返回节点个数
        if(points.length<=2)
        {
            return points.length;
        }
        int maxNumOfPoints=2;
        //对比所有节点
        for(int i=0;i<points.length;i++)
        {
            //此斜率上已有点的数量,不包括起点
            HashMap<String,Integer> k_point=new HashMap<>();
            //定义一些辅助结构
            int vCnt=0;//垂直线上的点
            int rCnt=1;//重合的点 自身已有一个
            int hCnt=0;//水平的点
            //记录HashMap中的最大值 免去遍历HashMap的过程
            int mapMaxValue=0;
            for(int j=i+1;j<points.length;j++)
            {
                int k_x=points[i].x-points[j].x;//x1-x2
                int k_y=points[i].y-points[j].y;//y1-y2
                //同为零
                if(k_x==0&&k_y==0)
                {
                    rCnt++;//和起点重合的点多一个
                }
                else if(k_x==0)//斜率无穷大
                {
                    vCnt++;//垂直线上的点
                }
                else if(k_y==0) //斜率为零
                {
                    hCnt++;//水平线上的点
                }
                else
                {
                    //获取此斜率的字符串表示形式 
                    String k=getKReference(k_x,k_y);
                    int kValue=0;//本次放入的斜率的相同的点数量
                    //如果已经出现过此斜率 将出现次数加1
                    if(k_point.containsKey(k))
                    {
                        kValue=k_point.get(k)+1;
                        k_point.put(k,kValue);
                        //记录Map中的最大值
                    }
                    //否则将此斜率表示加入Map中
                    else
                    {
                        k_point.put(k,1);
                        kValue=1;
                    }
                    if(mapMaxValue<kValue)
                   {
                       mapMaxValue=kValue;
                   }
                }
            }//从i出发的点遍历完成 (内存for循环结束)
            //比较一次出现最多的点
            mapMaxValue=mapMaxValue>vCnt?mapMaxValue:vCnt;//斜率最大点和普通点
            mapMaxValue=mapMaxValue>hCnt?mapMaxValue:hCnt;//斜率为零的点和普通点
            maxNumOfPoints=maxNumOfPoints>mapMaxValue+rCnt?maxNumOfPoints:mapMaxValue+rCnt;
        }
        return maxNumOfPoints;
    }
    /**********************
    *获取斜率的字符串表示形式
    *实现思想为将横纵坐标表示的最简比值的形式
    * 一正一负时,横坐标为正
    * 同为负时 设置为同为正
    **********************/
    private String getKReference(int k_x,int k_y)
    {
        int x=Math.abs(k_x);
        int y=Math.abs(k_y);
        //比较大小 
        if(x<y)
        {
            int temp=x;
            x=y;
            y=temp;
        }
        int r=x%y;
        while(r!=0)
        {
            x=y;
            y=r;
            r=x%y;
        }
        k_x/=y;
        k_y/=y;
        //避免异号
        if(k_x*k_y<0)
        {
            if(k_x<0)
            {
                k_x=-k_x;
                k_y=-k_y;
            }
        }
        else if(k_x<0&&k_y<0)//同号均为-时 设置为正
        {
            k_x=-k_x;
            k_y=-k_y;
        }
        return k_y+"/"+k_x;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值