Skip to content

Commit 28b467c

Browse files
committed
feat: add solutions to lc problem: No.0149
No.0149.Max Points on a Line
1 parent be6cd60 commit 28b467c

File tree

7 files changed

+462
-288
lines changed

7 files changed

+462
-288
lines changed

solution/0100-0199/0149.Max Points on a Line/README.md

Lines changed: 196 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,17 @@
3939

4040
<!-- 这里可写通用的实现逻辑 -->
4141

42-
在平面上确定一个点 `points[i]`,其他点与 `point[i]` 可以求得一个斜率,斜率相同的点意味着它们与 `points[i]` 在同一条直线上。
42+
**方法一:暴力枚举**
4343

44-
所以可以用哈希表作为计数器,其中斜率作为 key,然后累计当前点相同的斜率出现的次数。斜率可能是小数,我们可以用分数形式表示,先求分子分母的最大公约数,然后约分,最后将“分子.分母” 作为 key 即可
44+
我们可以枚举任意两个点 $(x_1, y_1), (x_2, y_2)$,把这两个点连成一条直线,那么此时这条直线上的点的个数就是 2,接下来我们再枚举其他点 $(x_3, y_3)$,判断它们是否在同一条直线上,如果在,那么直线上的点的个数就加 1,如果不在,那么直线上的点的个数不变。找出所有直线上的点的个数的最大值,即为答案
4545

46-
需要注意,如果平面上有和当前点重叠的点,如果进行约分,会出现除 0 的情况,那么我们单独用一个变量 duplicate 统计重复点的个数,重复点一定是过当前点的直线的。
46+
时间复杂度 $O(n^3)$,空间复杂度 $O(1)$。其中 $n$ 是数组 `points` 的长度。
47+
48+
**方法二:枚举 + 哈希表**
49+
50+
我们可以枚举一个点 $(x_1, y_1)$,把其他所有点 $(x_2, y_2)$ 与 $(x_1, y_1)$ 连成的直线的斜率存入哈希表中,斜率相同的点在同一条直线上,哈希表的键为斜率,值为直线上的点的个数。找出哈希表中的最大值,即为答案。为了避免精度问题,我们可以将斜率 $\frac{y_2 - y_1}{x_2 - x_1}$ 进行约分,约分的方法是求最大公约数,然后分子分母同时除以最大公约数,将求得的分子分母作为哈希表的键。
51+
52+
时间复杂度 $O(n^2 \times \log m)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是数组 `points` 的长度和数组 `points` 所有横纵坐标差的最大值。
4753

4854
<!-- tabs:start -->
4955

@@ -54,30 +60,41 @@
5460
```python
5561
class Solution:
5662
def maxPoints(self, points: List[List[int]]) -> int:
57-
def gcd(a, b) -> int:
63+
n = len(points)
64+
ans = 1
65+
for i in range(n):
66+
x1, y1 = points[i]
67+
for j in range(i + 1, n):
68+
x2, y2 = points[j]
69+
cnt = 2
70+
for k in range(j + 1, n):
71+
x3, y3 = points[k]
72+
a = (y2 - y1) * (x3 - x1)
73+
b = (y3 - y1) * (x2 - x1)
74+
cnt += a == b
75+
ans = max(ans, cnt)
76+
return ans
77+
```
78+
79+
```python
80+
class Solution:
81+
def maxPoints(self, points: List[List[int]]) -> int:
82+
def gcd(a, b):
5883
return a if b == 0 else gcd(b, a % b)
5984

6085
n = len(points)
61-
if n < 3:
62-
return n
63-
res = 0
64-
for i in range(n - 1):
65-
counter = Counter()
66-
t_max = duplicate = 0
86+
ans = 1
87+
for i in range(n):
88+
x1, y1 = points[i]
89+
cnt = Counter()
6790
for j in range(i + 1, n):
68-
delta_x = points[i][0] - points[j][0]
69-
delta_y = points[i][1] - points[j][1]
70-
if delta_x == 0 and delta_y == 0:
71-
duplicate += 1
72-
continue
73-
g = gcd(delta_x, delta_y)
74-
d_x = delta_x // g
75-
d_y = delta_y // g
76-
key = f'{d_x}.{d_y}'
77-
counter[key] += 1
78-
t_max = max(t_max, counter[key])
79-
res = max(res, t_max + duplicate + 1)
80-
return res
91+
x2, y2 = points[j]
92+
dx, dy = x2 - x1, y2 - y1
93+
g = gcd(dx, dy)
94+
k = (dx // g, dy // g)
95+
cnt[k] += 1
96+
ans = max(ans, cnt[k] + 1)
97+
return ans
8198
```
8299

83100
### **Java**
@@ -88,31 +105,46 @@ class Solution:
88105
class Solution {
89106
public int maxPoints(int[][] points) {
90107
int n = points.length;
91-
if (n < 3) {
92-
return n;
93-
}
94-
int res = 0;
95-
for (int i = 0; i < n - 1; ++i) {
96-
Map<String, Integer> kCounter = new HashMap<>();
97-
int max = 0;
98-
int duplicate = 0;
108+
int ans = 1;
109+
for (int i = 0; i < n; ++i) {
110+
int x1 = points[i][0], y1 = points[i][1];
99111
for (int j = i + 1; j < n; ++j) {
100-
int deltaX = points[i][0] - points[j][0];
101-
int deltaY = points[i][1] - points[j][1];
102-
if (deltaX == 0 && deltaY == 0) {
103-
++duplicate;
104-
continue;
112+
int x2 = points[j][0], y2 = points[j][1];
113+
int cnt = 2;
114+
for (int k = j + 1; k < n; ++k) {
115+
int x3 = points[k][0], y3 = points[k][1];
116+
int a = (y2 - y1) * (x3 - x1);
117+
int b = (y3 - y1) * (x2 - x1);
118+
if (a == b) {
119+
++cnt;
120+
}
105121
}
106-
int gcd = gcd(deltaX, deltaY);
107-
int dX = deltaX / gcd;
108-
int dY = deltaY / gcd;
109-
String key = dX + "." + dY;
110-
kCounter.put(key, kCounter.getOrDefault(key, 0) + 1);
111-
max = Math.max(max, kCounter.get(key));
122+
ans = Math.max(ans, cnt);
112123
}
113-
res = Math.max(res, max + duplicate + 1);
114124
}
115-
return res;
125+
return ans;
126+
}
127+
}
128+
```
129+
130+
```java
131+
class Solution {
132+
public int maxPoints(int[][] points) {
133+
int n = points.length;
134+
int ans = 1;
135+
for (int i = 0; i < n; ++i) {
136+
int x1 = points[i][0], y1 = points[i][1];
137+
Map<String, Integer> cnt = new HashMap<>();
138+
for (int j = i + 1; j < n; ++j) {
139+
int x2 = points[j][0], y2 = points[j][1];
140+
int dx = x2 - x1, dy = y2 - y1;
141+
int g = gcd(dx, dy);
142+
String k = (dx / g) + "." + (dy / g);
143+
cnt.put(k, cnt.getOrDefault(k, 0) + 1);
144+
ans = Math.max(ans, cnt.get(k) + 1);
145+
}
146+
}
147+
return ans;
116148
}
117149

118150
private int gcd(int a, int b) {
@@ -121,45 +153,144 @@ class Solution {
121153
}
122154
```
123155

156+
### **C++**
157+
158+
```cpp
159+
class Solution {
160+
public:
161+
int maxPoints(vector<vector<int>>& points) {
162+
int n = points.size();
163+
int ans = 1;
164+
for (int i = 0; i < n; ++i) {
165+
int x1 = points[i][0], y1 = points[i][1];
166+
for (int j = i + 1; j < n; ++j) {
167+
int x2 = points[j][0], y2 = points[j][1];
168+
int cnt = 2;
169+
for (int k = j + 1; k < n; ++k) {
170+
int x3 = points[k][0], y3 = points[k][1];
171+
int a = (y2 - y1) * (x3 - x1);
172+
int b = (y3 - y1) * (x2 - x1);
173+
cnt += a == b;
174+
}
175+
ans = max(ans, cnt);
176+
}
177+
}
178+
return ans;
179+
}
180+
};
181+
```
182+
183+
```cpp
184+
class Solution {
185+
public:
186+
int gcd(int a, int b) {
187+
return b == 0 ? a : gcd(b, a % b);
188+
}
189+
int maxPoints(vector<vector<int>>& points) {
190+
int n = points.size();
191+
int ans = 1;
192+
for (int i = 0; i < n; ++i) {
193+
int x1 = points[i][0], y1 = points[i][1];
194+
unordered_map<string, int> cnt;
195+
for (int j = i + 1; j < n; ++j) {
196+
int x2 = points[j][0], y2 = points[j][1];
197+
int dx = x2 - x1, dy = y2 - y1;
198+
int g = gcd(dx, dy);
199+
string k = to_string(dx / g) + "." + to_string(dy / g);
200+
cnt[k]++;
201+
ans = max(ans, cnt[k] + 1);
202+
}
203+
}
204+
return ans;
205+
}
206+
};
207+
```
208+
124209
### **Go**
125210

126211
```go
127212
func maxPoints(points [][]int) int {
128-
type pair struct {
129-
first int
130-
second int
131-
}
132213
n := len(points)
133-
if n <= 2 {
134-
return n
214+
ans := 1
215+
for i := 0; i < n; i++ {
216+
x1, y1 := points[i][0], points[i][1]
217+
for j := i + 1; j < n; j++ {
218+
x2, y2 := points[j][0], points[j][1]
219+
cnt := 2
220+
for k := j + 1; k < n; k++ {
221+
x3, y3 := points[k][0], points[k][1]
222+
a := (y2 - y1) * (x3 - x1)
223+
b := (y3 - y1) * (x2 - x1)
224+
if a == b {
225+
cnt++
226+
}
227+
}
228+
if ans < cnt {
229+
ans = cnt
230+
}
231+
}
135232
}
136-
ans := 0
137-
for i := 0; i < n-1; i++ {
138-
freq := make(map[pair]int)
233+
return ans
234+
}
235+
```
236+
237+
```go
238+
func maxPoints(points [][]int) int {
239+
n := len(points)
240+
ans := 1
241+
type pair struct{ x, y int }
242+
for i := 0; i < n; i++ {
243+
x1, y1 := points[i][0], points[i][1]
244+
cnt := map[pair]int{}
139245
for j := i + 1; j < n; j++ {
140-
x1, y1, x2, y2 := points[i][0], points[i][1], points[j][0], points[j][1]
246+
x2, y2 := points[j][0], points[j][1]
141247
dx, dy := x2-x1, y2-y1
142248
g := gcd(dx, dy)
143-
p := pair{dx / g, dy / g}
144-
freq[p]++
145-
ans = max(ans, freq[p]+1)
249+
k := pair{dx / g, dy / g}
250+
cnt[k]++
251+
if ans < cnt[k]+1 {
252+
ans = cnt[k] + 1
253+
}
146254
}
147255
}
148256
return ans
149257
}
150258

151259
func gcd(a, b int) int {
152-
for b != 0 {
153-
a, b = b, a%b
260+
if b == 0 {
261+
return a
154262
}
155-
return a
263+
return gcd(b, a%b)
156264
}
265+
```
157266

158-
func max(a, b int) int {
159-
if a > b {
160-
return a
161-
}
162-
return b
267+
### **C#**
268+
269+
```cs
270+
public class Solution {
271+
public int MaxPoints(int[][] points) {
272+
int n = points.Length;
273+
int ans = 1;
274+
for (int i = 0; i < n; ++i) {
275+
int x1 = points[i][0], y1 = points[i][1];
276+
for (int j = i + 1; j < n; ++j) {
277+
int x2 = points[j][0], y2 = points[j][1];
278+
int cnt = 2;
279+
for (int k = j + 1; k < n; ++k) {
280+
int x3 = points[k][0], y3 = points[k][1];
281+
int a = (y2 - y1) * (x3 - x1);
282+
int b = (y3 - y1) * (x2 - x1);
283+
if (a == b) {
284+
++cnt;
285+
}
286+
}
287+
if (ans < cnt) {
288+
ans = cnt;
289+
}
290+
}
291+
}
292+
return ans;
293+
}
163294
}
164295
```
165296

0 commit comments

Comments
 (0)