LeetCode困難刷題記錄——Max Points on a Line 直線上最多的點數

問題:

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

給定一個二維平面,平面上有 個點,求最多有多少個點在同一條直線上。

 

分析:

根據兩點確定一條直線原理,我們可以選取兩個點確定一條直線,再看看其他的點有多少位於這條直線上,這題主要思路就這麼簡單,之所以是個困難題,因爲有很多特殊情況要考慮

第一,斜率的計算,如果用除法計算斜率,會有斜率爲無窮大的問題,另外除法的結果是浮點數,可能會有不精確的問題,所以我們使用乘法來進行斜率的比較,當然乘法也要注意,int的乘法結果可能會超出上限,要用long來保存乘法結果

第二,重複點的問題,如果一開始選取用來確定一條直線的兩個點是重複點就會造成問題,應該跳過這種情況

 

代碼:

/**
 * 直線上最多的點數
 * Max Points on a Line
 *
 * @author DongWei
 * @date 2019/5/22
 */
class Solution {
    public int maxPoints(int[][] points) {
        // 如果總座標點少於 3 個,直接返回答案
        int n = points.length;
        if (points.length <= 2) return n;

        // 搜索直線上最多的點數
        int max = 0;
        for (int i = 0; i < n; i ++) {
            // same 表示有多少個和 i 一樣的點
            int same = 1;
            for (int j = i + 1; j < n; j ++) {
                // cnt 表示除了 i 座標點外,有多少個點在 i、j 座標點構成的直線上
                int cnt = 0;
                if (points[i][0] == points[j][0] && points[i][1] == points[j][1]) {
                    // i、j 是重複點,計數
                    same ++;
                } else {
                    // i、j 不是重複點,檢查其他點是否在這條直線上,j 座標點也在這條直線上,所以 cnt ++
                    cnt ++;
                    long xDiff = (long)(points[i][0] - points[j][0]);
                    long yDiff = (long)(points[i][1] - points[j][1]);
                    for (int k = j + 1; k < n; k ++) {
                        if (xDiff * (points[i][1] - points[k][1]) == yDiff * (points[i][0] - points[k][0])) {
                            cnt ++;
                        }
                    }
                }
                // 最大值比較
                max = Math.max(max, cnt + same);
            }
        }
        return max;
    }
}

這個代碼跑起來在20ms以內,最快能到10ms,每次結果都不一樣

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