# 149. Max Points on a Line (Hard)

https://leetcode.com/problems/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.

Example 1:

```Input: [[1,1],[2,2],[3,3]]
Output: 3
Explanation:
^
|
|        o
|     o
|  o
+------------->
0  1  2  3  4
```

Example 2:

```Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
Output: 4
Explanation:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6
```

## Solutions

``````class Solution {

// Be careful of the special cases, same points may occurs more than one times.

public int maxPoints(int[][] points) {
int ans = 0;

if (points == null || points.length == 0) {
return ans;
}

int len = points.length;

if (len <= 2) {
return len;
}

Map<String, Set<Integer>> lineMap = new HashMap<>();

for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {

// vector from points[j] to points[i], b/a is the slope of the line
int a = points[i][0] - points[j][0];
int b = points[i][1] - points[j][1];

String key;

// a == 0 represents a vertical line;
if (a == 0) {
key = "x=" + points[i][0];
}
// b == 0 represents a horizontal line
else if (b == 0) {
key = "y=" + points[i][1];
} else {
int g = gcd(a, b);
if (g != 0) {
a = a / g;
b = b / g;
}

// y = b/a * x + c --> ay = bx + ac --> c = (ay - bx) / a --> c = m / n
int m = (a * points[i][1] - b * points[i][0]);
int n = a;

g = gcd(m, n);
if (n!= 0 && g != 0) {
m = m / g;
n = n / g;
}

key = a + "#" + b + "#" + m + "#" + n;
}

if (!lineMap.containsKey(key)) {
lineMap.put(key, new HashSet<>());
}

}
}

int max = 0;
for (String key : lineMap.keySet()) {
max = Math.max(max, lineMap.get(key).size());
}

return max;
}

private int gcd(int a, int b) {
if (a == 0) {
return b;
}

return a / Math.abs(a) * Math.abs(gcd(b % a, a));
}
}
``````