LeetCode 149 Max Points on a Line (C++, Python)

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



Solution C++


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
 
struct VecHash {
    size_t operator() (const pair<int, int>& p) const {
        hash<int>()(p.first) ^ hash<int>()(p.second);
    }
};

class Solution {
private:
    int gcd(int x, int y) {
        if (x < y) return gcd(y, x);
        while (y) {
            int tmp = y;
            y = x % y;
            x = tmp;
        }
        return x;
    }
    pair<int, int> reduceVec(int x, int y) {
        if (x == 0) return {0, 1};
        if (y == 0) return {1, 0};
        int g = gcd(x, y);
        return {x / g, y / g};
    } 
public:
    int maxPoints(vector<Point> &points) {
        if (points.size() < 3) return points.size();
        auto comp = [](const Point& a, const Point& b) {
            if (a.x == b.x) return a.y < b.y;
            return a.x < b.x;
        };
        sort(points.begin(), points.end(), comp);
        int maxNum = 1;
        unordered_map<pair<int, int>, int, VecHash> vecmap;
        for (int i = 0; i < points.size();) {
            vecmap.clear();
            int same = 1;
            int j = i + 1;
            while (j < points.size() && points[i].x == points[j].x && points[i].y == points[j].y) {
                ++same;
                ++j;
            }
            if (j == points.size()) {maxNum = max(maxNum, same); break;}
            int ni = j;
            while (j < points.size()) {
                int num = 1;
                int dx = points[j].x - points[i].x;
                int dy = points[j].y - points[i].y;
                auto vec = reduceVec(dx, dy);
                if (vecmap.find(vec) == vecmap.end()) {
                    vecmap[vec] = 1;   
                } else {
                    vecmap[vec] ++; 
                }
                maxNum = max(maxNum, vecmap[vec] + same);
                ++j;
            }
            i = ni;
        }
        return maxNum;
    }
};

Solution Python


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Definition for a point.
# class Point:
#     def __init__(self, a=0, b=0):
#         self.x = a
#         self.y = b
from fractions import gcd
class Solution:
    def reduceVec(self, x, y):
        if x == 0: return (0, 1)
        if y == 0: return (1, 0)
        g = gcd(x, y)
        return (x/g, y/g)
    # @param {Point[]} points
    # @return {integer}
    def maxPoints(self, points):
        points.sort(lambda p1, p2: cmp(p1.y, p2.y) if (p1.x == p2.x) else cmp(p1.x, p2.x))
        maxLen = 0
        i = 0
        vecmap = {}
        while i < len(points):
            vecmap.clear()
            same = 1
            j = i + 1
            while j < len(points) and points[i].x == points[j].x and points[i].y == points[j].y:
                same += 1
                j += 1
            if j == len(points):
                maxLen = max(maxLen, same)
                break
            ni = j
            while j < len(points):
                dx = points[j].x - points[i].x
                dy = points[j].y - points[i].y
                vx, vy = self.reduceVec(dx, dy)
                if (vx, vy) in vecmap:
                    vecmap[(vx, vy)] += 1
                else:
                    vecmap[(vx, vy)] = 1
                j += 1
                maxLen = max(maxLen, same + vecmap[(vx, vy)])
            i = ni
        return maxLen

Popular posts from this blog

How Django Works (4) URL Resolution

Python Class Method and Class Only Method

How Django works (3): Testing Server and Static Files Serving