39
39
40
40
<!-- 这里可写通用的实现逻辑 -->
41
41
42
- 在平面上确定一个点 ` points[i] ` ,其他点与 ` point[i] ` 可以求得一个斜率,斜率相同的点意味着它们与 ` points[i] ` 在同一条直线上。
42
+ ** 方法一:暴力枚举 **
43
43
44
- 所以可以用哈希表作为计数器,其中斜率作为 key,然后累计当前点相同的斜率出现的次数。斜率可能是小数,我们可以用分数形式表示,先求分子分母的最大公约数,然后约分,最后将“分子.分母” 作为 key 即可 。
44
+ 我们可以枚举任意两个点 $(x_1, y_1), (x_2, y_2)$,把这两个点连成一条直线,那么此时这条直线上的点的个数就是 2,接下来我们再枚举其他点 $(x_3, y_3)$,判断它们是否在同一条直线上,如果在,那么直线上的点的个数就加 1,如果不在,那么直线上的点的个数不变。找出所有直线上的点的个数的最大值,即为答案 。
45
45
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 ` 所有横纵坐标差的最大值。
47
53
48
54
<!-- tabs:start -->
49
55
54
60
``` python
55
61
class Solution :
56
62
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 ):
58
83
return a if b == 0 else gcd(b, a % b)
59
84
60
85
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()
67
90
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
81
98
```
82
99
83
100
### ** Java**
@@ -88,31 +105,46 @@ class Solution:
88
105
class Solution {
89
106
public int maxPoints (int [][] points ) {
90
107
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 ];
99
111
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
+ }
105
121
}
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);
112
123
}
113
- res = Math . max(res, max + duplicate + 1 );
114
124
}
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;
116
148
}
117
149
118
150
private int gcd (int a , int b ) {
@@ -121,45 +153,144 @@ class Solution {
121
153
}
122
154
```
123
155
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
+
124
209
### ** Go**
125
210
126
211
``` go
127
212
func maxPoints (points [][]int ) int {
128
- type pair struct {
129
- first int
130
- second int
131
- }
132
213
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
+ }
135
232
}
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 {}
139
245
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 ]
141
247
dx , dy := x2-x1, y2-y1
142
248
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
+ }
146
254
}
147
255
}
148
256
return ans
149
257
}
150
258
151
259
func gcd (a , b int ) int {
152
- for b ! = 0 {
153
- a, b = b, a%b
260
+ if b = = 0 {
261
+ return a
154
262
}
155
- return a
263
+ return gcd (b, a%b)
156
264
}
265
+ ```
157
266
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
+ }
163
294
}
164
295
```
165
296
0 commit comments