149. Max Points on a Line

First, let's talk about mathematics.

How to determine if three points are on the same line?

The answer is to see if slopes of arbitrary two pairs are the same.

Second, let's see what the minimum time complexity can be.

Definitely, O(n^2). It's because you have to calculate all slopes between any two points.

Given point A, we need to calculate all slopes between A and other points. There will be three cases:

  1. Some other point is the same as point A.

  2. Some other point has the same x coordinate as point A, which will result to a positive infinite slope.

  3. General case. We can calculate slope.

We can store all slopes in a hash table. And we find which slope shows up mostly. Then add the number of same points to it. Then we know the maximum number of points on the same line for point A.

  1. use hashmap, ่จˆ็ฎ—็›ธๅŒ็š„ๆ–œ็Ž‡็š„ count

  2. ้‡ๅˆ็š„้ปž่ฆๅ€‹ๅˆฅ่จˆ็ฎ—, ๆœ€ๅพŒๅŠ ๅˆฐ็ตๆžœ ๏ผˆ้กŒ็›ฎๅพŒไพ†ๆœ‰ๆ”น้Ž, ็พๅœจๆ‰€ๆœ‰้ปž้ƒฝๆ˜ฏ unique ็š„

  3. dy/dx ่จˆ็ฎ—ๆ–œ็Ž‡, ้œ€่ฆ้™คๆณ•, ้€™ๆ˜ฏไธๅฎ‰ๅ…จ็š„, ็”จ double ๅญ˜ๆ–œ็Ž‡ๆ˜ฏไธๅฏ้ ็š„, ็ฒพๅบฆไธๅค , ๆ‰€ไปฅไธ็œŸ็š„่จˆ็ฎ— slope,

  4. ไฝ†ไธ่จˆ็ฎ— slope ็š„่ฉฑ, ้œ€่ฆๅ…ˆ็ฎ—ๅ‡บ dy, dx ็š„ GCD,

dy, dx ๅฆ‚ๆžœๆ˜ฏไบ’่ณช, ้ƒฝๆ˜ฏๆœ€็ฐกๅˆ†ๆ•ธ, ้‚ฃ็ฎ—ๅ‡บไพ†็š„ๆ–œ็Ž‡ๆ‰ๆœƒๆ˜ฏ unique ็š„, ่ฆ้”ๅˆฐไบ’่ณช: ๅš็ด„ๅˆ†, ๆ‰€ไปฅ้œ€่ฆ GCD

int a = dy/ gcd(dy, dx)

int b = dx/ gcd(dy, dx)

็„ถๅพŒ็›ดๆŽฅๆ‹ฟ a, b ็•ถๆˆ key ไพ†็”จ, ไธ็”จ่จˆ็ฎ— slope! ้€™่ฃก็›ดๆŽฅๆ‹ฟ a +"," + b ็•ถ hashmap key

ๅฆ‚ๆžœ็”จ double ๅƒ้€™ๆจฃ, ๅทฎ่ทๅพฎไนŽๅ…ถๅพฎ, double ่จˆ็ฎ—ๅ‡บไพ†็š„ๆ–œ็Ž‡ๆœƒๆ˜ฏไธ€ๆจฃ็š„

็‚บไป€้บผๅฏไปฅ็”จๆ–œ็Ž‡ไพ†ๆฑ‚ๅ‘ข๏ผŸ ไธ‰้ปžๆƒณ่ฆๅ…ฑ็ทš (a, b,c), ๅ›บๅฎšไธ€ๅ€‹้ปž, ไธ€ๅฎšๆœ‰ๅ…ฉๅฐๆ–œ็Ž‡ๆ˜ฏไธ€ๆจฃ็š„(a,b ๆ–œ็Ž‡ ่ทŸ a, c ๆ–œ็Ž‡ไธ€ๆจฃ), ๆ‰€ไปฅ้œ€่ฆๅ…ฉๅ…ฉๅŽปๆฏ”่ผƒ, ๆ‰€ไปฅ time complexity ๆœƒๆ˜ฏ O(n^2)

T: O(n^2), n is number of points

S: O(n)

ๆœ‰่จˆ็ฎ—้‡่ค‡็š„้ปž็š„็‰ˆๆœฌ:

class Solution {
    public int maxPoints(int[][] points) {
        int m = points.length;
        Map<String, Integer> map;
        int res = 0;
        
        for (int i = 0; i < m; i++) {
            map = new HashMap<>();
            int max = 0;
            int duplicate = 0;
            for (int j = i+1; j < m; j++) {
                int deltaX = points[j][0] - points[i][0];
                int deltaY = points[j][1] - points[i][1];
                if (deltaX == 0 && deltaY == 0) {
                    duplicate++;
                    continue;
                }
                
                int gcd = gcd(deltaX, deltaY);
                int dx = deltaX/gcd;
                int dy = deltaY/gcd;
                
                String key = dx + "," + dy;
                map.put(key, map.getOrDefault(key, 0)+1);
                max = Math.max(max, map.get(key));
            }
            res = Math.max(res, max + duplicate + 1); // ้€™ๅ€‹ +1. ๆ˜ฏ i ๅ›บๅฎš็š„้‚ฃไธ€ๅ€‹้ปž
        }
        return res;
    }
    private int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a%b);
    }
}

no duplicate:

class Solution {
    public int maxPoints(int[][] points) {
        int m = points.length;
        Map<String, Integer> map;
        int res = 0;
        
        for (int i = 0; i < m; i++) {
            map = new HashMap<>();
            int max = 0;
            for (int j = i+1; j < m; j++) {
                int deltaX = points[j][0] - points[i][0];
                int deltaY = points[j][1] - points[i][1];
                
                int gcd = gcd(deltaX, deltaY);
                int dx = deltaX/gcd;
                int dy = deltaY/gcd;
                
                String key = dx + "," + dy;
                map.put(key, map.getOrDefault(key, 0)+1);
                max = Math.max(max, map.get(key));
            }
            res = Math.max(res, max + 1); // ้€™ๅ€‹ +1. ๆ˜ฏ i ๅ›บๅฎš็š„้‚ฃไธ€ๅ€‹้ปž
        }
        return res;
    }
    private int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a%b);
    }
}

Last updated