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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章