forked from lzl124631x/LeetCode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paths1.cpp
More file actions
54 lines (52 loc) · 1.74 KB
/
s1.cpp
File metadata and controls
54 lines (52 loc) · 1.74 KB
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
// OJ: https://leetcode.com/problems/max-points-on-a-line/
// Author: github.com/lzl124631x
// Time: O(N^3)
// In worse case, when visiting ith point, there will be O(i^2)
// lines, but all the lines are of constant size 2. So in
// sum it's O(N^3), not O(N^4).
// Space: O(N^2)
namespace std {
template <> struct hash<Point> {
std::size_t operator () (const Point &p) const {
return hash<int>()(p.x) ^ hash<int>()(p.y);
}
};
}
bool operator==(const Point& a, const Point& b) {
return a.x == b.x && a.y == b.y;
}
class Solution {
private:
bool onSameLine(Point &a, Point &b, Point &c) {
return (long long)(a.x - b.x) * (a.y - c.y) == (long long)(a.x - c.x) * (a.y - b.y);
}
public:
int maxPoints(vector<Point>& points) {
if (points.size() <= 2) return points.size();
unordered_map<Point, int> m;
for (auto p : points) m[p]++;
vector<pair<Point, int>> ps(m.begin(), m.end());
vector<vector<int>> lines(1, vector<int>{ 0, 1 });
int N = ps.size();
for (int i = 2; i < N; ++i) {
auto &p = ps[i].first;
vector<int> bad(i, 1);
for (auto &line : lines) {
auto &p1 = ps[line[0]].first, &p2 = ps[line[1]].first;
if (!onSameLine(p1, p2, p)) continue;
for (int neighbor : line) bad[neighbor] = 0;
line.push_back(i);
}
for (int j = 0; j < i; ++j) {
if (bad[j]) lines.emplace_back(vector<int>{ j, i });
}
}
int ans = 2;
for (auto line : lines) {
int cnt = 0;
for (auto i : line) cnt += ps[i].second;
ans = max(ans, cnt);
}
return ans;
}
};