33https://leetcode-cn.com/problems/max-points-on-a-line/
44
55## 题目描述
6-
6+ - [ 149. 直线上最多的点数] ( #149-直线上最多的点数 )
7+ - [ 题目描述] ( #题目描述 )
8+ - [ 方法 1:枚举] ( #方法-1枚举 )
9+ - [ 思路] ( #思路 )
10+ - [ 复杂度分析] ( #复杂度分析 )
11+ - [ 代码] ( #代码 )
12+ - [ 方法 2: 哈希表] ( #方法-2-哈希表 )
13+ - [ 思路] ( #思路-1 )
14+ - [ 复杂度分析] ( #复杂度分析-1 )
15+ - [ 代码] ( #代码-1 )
716```
817给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。
918
1019
1120
1221示例 1:
1322```
23+
1424![ ] ( https://assets.leetcode.com/uploads/2021/02/25/plane1.jpg )
25+
1526```
1627输入:points = [[1,1],[2,2],[3,3]]
1728输出:3
1829示例 2:
1930```
31+
2032![ ] ( https://assets.leetcode.com/uploads/2021/02/25/plane2.jpg )
33+
2134```
2235输入:points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
2336输出:4
@@ -51,8 +64,8 @@ points 中的所有点 互不相同
5164
5265### 复杂度分析
5366
54- - 时间复杂度:$O(N^3)$,枚举直线的时间是 $O(N^2)$,计算在直线上的点的时间是 $O(N)$。
55- - 空间复杂度:$O(1)$。
67+ - 时间复杂度:$O(N^3)$,枚举直线的时间是 $O(N^2)$,计算在直线上的点的时间是 $O(N)$。
68+ - 空间复杂度:$O(1)$。
5669
5770### 代码
5871
@@ -63,33 +76,32 @@ JavaScript Code
6376 * @param {number[][]} points
6477 * @return {number}
6578 */
66- var maxPoints = function (points ) {
67- let max = 1 ;
68- // 点两两组合,枚举所有组合
69- for (let i = 0 ; i < points .length ; i++ ) {
70- for (let j = i + 1 ; j < points .length ; j++ ) {
71- // points[i] 和 points[j] 确定了一条直线
72- // 计算在这条直线上的点
73- const count = countPointsOnLine (points[i], points[j]);
74- max = Math .max (max, count);
75- }
76- }
77- return max;
78-
79- // *********************************************
80-
81- function countPointsOnLine ([x1 , y1 ], [x2 , y2 ]) {
82- const slopeOfLine = (y1 - y2) / (x1 - x2);
83- let count = 2 ;
84- points .forEach (([x , y ]) => {
85- if (x === x1 && y === y1) return
86- if (x === x2 && y === y2) return
87- // 斜率一样则说明点在线上
88- const slope = (y1 - y) / (x1 - x);
89- if (slope === slopeOfLine) count++
90- })
91- return count;
79+ var maxPoints = function (points ) {
80+ let max = 1 ;
81+ // 点两两组合,枚举所有组合的直线
82+ for (let i = 0 ; i < points .length ; i++ ) {
83+ for (let j = i + 1 ; j < points .length ; j++ ) {
84+ // points[i] 和 points[j] 确定了一条直线
85+ // 计算在这条直线上的点
86+ let count = 2 ;
87+ for (let k = j + 1 ; k < points .length ; k++ ) {
88+ if (areSameLine (points[i], points[j], points[k])) count++
89+ }
90+ max = Math .max (max, count);
9291 }
92+ }
93+ return max;
94+
95+ // *********************************************
96+ function areSameLine ([x1 , y1 ], [x2 , y2 ], [x3 , y3 ]) {
97+ if (x1 == x2 && x2 == x3) return true ;
98+ if (y1 == y2 && y2 == y3) return true ;
99+ if (x1 == x2 || x2 == x3) return false ;
100+ if (y1 == y2 || y2 == y3) return false ;
101+ const s1 = (y1 - y2) / (x1 - x2);
102+ const s2 = (y2 - y3) / (x2 - x3);
103+ return s1 === s2;
104+ }
93105};
94106```
95107
@@ -106,8 +118,8 @@ var maxPoints = function(points) {
106118
107119### 复杂度分析
108120
109- - 时间复杂度:$O(N^2* logm)$,枚举直线的时间是 $O(N^2)$,计算gcd的时间是 $O(logm)$,m 是点的最大差值。
110- - 空间复杂度:$O(N)$。
121+ - 时间复杂度:$O(N^2* logm)$,枚举直线的时间是 $O(N^2)$,计算 gcd 的时间是 $O(logm)$,m 是点的最大差值。
122+ - 空间复杂度:$O(N)$。
111123
112124### 代码
113125
@@ -119,31 +131,31 @@ JavaScript Code
119131 * @return {number}
120132 */
121133var maxPoints = function (points ) {
122- let max = 1 ;
123- for (let i = 0 ; i < points .length ; i++ ) {
124- // 先确定一个点 points[i]
125- const map = {};
126- for (let j = i + 1 ; j < points .length ; j++ ) {
127- // 枚举剩余的点,计算两点的斜率
128- // 用哈希表记录所有出现过的斜率的次数
129- const key = getSlopeKey (points[i], points[j]);
130- map[key] = (map[key] || 0 ) + 1 ;
131- }
132- const count = Math .max (... Object .values (map)) + 1 ;
133- max = Math .max (count, max);
134- }
135- return max
136-
137- // ***********************************
138- function getSlopeKey ([x1 , y1 ], [x2 , y2 ]) {
139- const [x , y ] = [x1 - x2, y1 - y2];
140- const k = gcd (x, y);
141- return ` ${ y / k} /${ x / k} ` ;
142- }
143- function gcd (a , b ) {
144- return b != 0 ? gcd (b, a % b) : a;
134+ let max = 1 ;
135+ for (let i = 0 ; i < points .length ; i++ ) {
136+ // 先确定一个点 points[i]
137+ const map = {};
138+ for (let j = i + 1 ; j < points .length ; j++ ) {
139+ // 枚举剩余的点,计算两点的斜率
140+ // 用哈希表记录所有出现过的斜率的次数
141+ const key = getSlopeKey (points[i], points[j]);
142+ map[key] = (map[key] || 0 ) + 1 ;
145143 }
144+ const count = Math .max (... Object .values (map)) + 1 ;
145+ max = Math .max (count, max);
146+ }
147+ return max;
148+
149+ // ***********************************
150+ function getSlopeKey ([x1 , y1 ], [x2 , y2 ]) {
151+ const [x , y ] = [x1 - x2, y1 - y2];
152+ const k = gcd (x, y);
153+ return ` ${ y / k} /${ x / k} ` ;
154+ }
155+ function gcd (a , b ) {
156+ return b != 0 ? gcd (b, a % b) : a;
157+ }
146158};
147159```
148160
149- 更多题解可以访问:[ https://github.com/suukii/91-days-algorithm ] ( https://github.com/suukii/91-days-algorithm )
161+ 更多题解可以访问:[ https://github.com/suukii/91-days-algorithm ] ( https://github.com/suukii/91-days-algorithm )
0 commit comments