編程題—給定位於二維平面上的n個點,求出位於同一條直線上的最大點數

開始拿到這個題的時候,首先就會想到兩點確定一條直線,若要判斷相應的點是否在同一條直線上,僅需求出它們的斜率即可。

但是此題需注意的幾點是:(1)當斜率不存在的情況:即(y2-y1)/(x2-x1)中(x2-x1)爲0的情況。

                                           (2)當斜率爲0的情況:即(y2-y1)爲0的情況。

                                           (3)最後需要注意的就是此題有一入坑點就是對斜率的存,一般我們可能會想到用double類型來存斜率,但是double類型也有精度不準的機率,導致程序出錯,所以在此我選擇了用最大公約數(最大公因子)gcd來使用分數來代替斜率(此時需要保證分子分母最簡)。

                                              即使用一個Map<Integer, Map<Integer, Integer>> map = new HashMao<>();

其中第一個Integer代表的是(x2-x1)/gcd, 即分母;內嵌的key代表的是(y2-y1)/gcd,即分子;value代表的是出現次斜率的次數。

                                              其中需要一個在每一次外部遍歷時記錄一個特殊情況計數器,即overLop.

 


import java.util.Map;
import java.util.HashMap;
/**
 * Definition for a point.
 * class Point {
 *     int x;
 *     int y;
 *     Point() { x = 0; y = 0; }
 *     Point(int a, int b) { x = a; y = b; }
 * }
 */
/*
    給定位於二維平面上的n個點,求出位於同一條直線上的最大點數
    思路:(1)位於同一直線上即就是斜率相同,用一個hashmap記錄下斜率和點數量的映射關係;
         (2)特殊情況:兩個點重合
*/
public class Solution {
    public int maxPoints(Point[] points) {
       if(points == null){
           return 0;
       }
        if(points.length <=2 ){
            return points.length;
        }
        
        Map<Integer, Map<Integer,Integer>> map = new HashMap<>();
        //設置最終的結果
        int res = 0;
        //設置每一輪比較後的最大值
        int max = 0;
          
        for(int i=0;i<points.length-1;i++){
            map.clear();
            int overLop=0;//考慮特殊情況
            max = 0;
            
            for(int j=i+1;j<points.length;j++){
                int x = points[j].x - points[i].x;
                int y = points[j].y - points[i].y;
                if(x == 0 && y == 0){
                    overLop++;
                    continue;
                }
                //計算最大公約數
                //想用分數代表斜率,必須保證分子分母最簡
                int gcd = generateor(x,y);
                if(gcd != 0){
                    x = x/gcd;
                    y = y/gcd;
                }
                if(map.containsKey(x)){
                    if(map.get(x).containsKey(y)){
                        map.get(x).put(y,map.get(x).get(y)+1);
                    }else{
                        map.get(x).put(y,1);
                    }
                }else{
                    Map<Integer,Integer> temp = new HashMap<>();
                    temp.put(y,1);
                    map.put(x,temp);
                }
                max = Math.max(max, map.get(x).get(y) ); 
            }
            res = Math.max(res, max+overLop+1);
        }
         return res;
    }
        
        private int generateor(int x, int y){//歐幾里得算法
            if(y == 0){
                return x;
            }
            return generateor(y, x%y);
        }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章