1. 程式人生 > 實用技巧 >LeetCode149. 直線上最多的點數

LeetCode149. 直線上最多的點數

首先想到的思路是:利用N皇后問題解法中,通過|a-i| == |b-j| 判斷 (a,b)和(i,j)是否在同一條斜線上。但是很多測試用例過不了。。。(例如[[0,0],[1,1],[1,-1]] 輸出2)

本題思路:固定一點, 找其他點和這個點組成直線, 統計他們的斜率!

class Solution {
    public int maxPoints(int[][] points) {
        /**
         *  思路: 一個點加一個斜率即可唯一確定一條直線,直線的 [點斜式]
         *         固定一點, 找其他點和這個點組成直線, 統計他們的斜率!
         *      本題關鍵是求斜率的方法:用最大約數方法(gcd), 化成最簡形式, 3/6 == 2/4 == 1/2
         
*/ if (points == null || points.length == 0) return 0; int n = points.length; if (n <= 2) return n; int res = 0; Map<String, Integer> map = new HashMap<>(); for (int i = 0; i < n; i++) { int tempMax = 0; //儲存經過當前點的直線中,最多的點 int
duplicate = 0; // repeat記錄和第i個點重複點的個數 for (int j = i + 1; j < n; j++) { //求出分子分母 int y = points[i][1] - points[j][1]; int x = points[i][0] - points[j][0]; if (y == 0 && x == 0) { //y=0=x表明第j個點和第i個點重合了 duplicate ++;
continue; } //求公約數,因為如果採用dy/dx的方式求斜率,如果是一條平行於y軸的線會造成除法錯誤 int g = gcd(y, x); // 約分 y /= g; x /= g; String key = String.valueOf(y) + "/" + String.valueOf(x); map.put(key, map.getOrDefault(key, 0) + 1); tempMax = Math.max(tempMax, map.get(key)); } //重合的點也算在一條直線上,且重合的點可以說在任意一條直線上 res = Math.max(res, tempMax + duplicate + 1); map.clear(); } return res; } // 求最大公約數 private int gcd(int y, int x) { // if (x == 0) return y; // return gcd(x, y % x); while (x != 0) { int temp = y % x; y = x; x = temp; } return y; } }

參考:

詳細通俗的思路分析,多解法

用斜率