149. 直线上最多的点数
Last updated
Last updated
## 方法 1:枚举
### 思路
这题其实不难,只需要知道两个朴素的数学知识:
- 两点确定一条直线
- 用斜率方程来判断某点是否在一条直线上
暴力点的思路就是,枚举所有两个点的组合:
- 先用两个点确定一条直线
- 枚举其他点,判断点是否在这条直线上
### 复杂度分析
- 时间复杂度:$O(N^3)$,枚举直线的时间是 $O(N^2)$,计算在直线上的点的时间是 $O(N)$。
- 空间复杂度:$O(1)$。
### 代码
JavaScript Code
```js
/**
* @param {number[][]} points
* @return {number}
*/
var maxPoints = function (points) {
let max = 1;
// 点两两组合,枚举所有组合的直线
for (let i = 0; i < points.length; i++) {
for (let j = i + 1; j < points.length; j++) {
// points[i] 和 points[j] 确定了一条直线
// 计算在这条直线上的点
let count = 2;
for (let k = j + 1; k < points.length; k++) {
if (areSameLine(points[i], points[j], points[k])) count++
}
max = Math.max(max, count);
}
}
return max;
// *********************************************
function areSameLine([x1, y1], [x2, y2], [x3, y3]) {
if (x1 == x2 && x2 == x3) return true;
if (y1 == y2 && y2 == y3) return true;
if (x1 == x2 || x2 == x3) return false;
if (y1 == y2 || y2 == y3) return false;
const s1 = (y1 - y2) / (x1 - x2);
const s2 = (y2 - y3) / (x2 - x3);
return s1 === s2;
}
};/**
* @param {number[][]} points
* @return {number}
*/
var maxPoints = function (points) {
let max = 1;
for (let i = 0; i < points.length; i++) {
// 先确定一个点 points[i]
const map = {};
for (let j = i + 1; j < points.length; j++) {
// 枚举剩余的点,计算两点的斜率
// 用哈希表记录所有出现过的斜率的次数
const key = getSlopeKey(points[i], points[j]);
map[key] = (map[key] || 0) + 1;
}
const count = Math.max(...Object.values(map)) + 1;
max = Math.max(count, max);
}
return max;
// ***********************************
function getSlopeKey([x1, y1], [x2, y2]) {
const [x, y] = [x1 - x2, y1 - y2];
const k = gcd(x, y);
return `${y / k}/${x / k}`;
}
function gcd(a, b) {
return b != 0 ? gcd(b, a % b) : a;
}
};