Skip to content

Commit 0e5748a

Browse files
committed
update: 149. 直线上最多的点数
1 parent e358a55 commit 0e5748a

File tree

1 file changed

+67
-55
lines changed

1 file changed

+67
-55
lines changed

basic/hashmap/ext-max-points-on-a-line.md

Lines changed: 67 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,34 @@
33
https://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
*/
121133
var 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

Comments
 (0)