「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战」。
说在前面
有一些人认为前端并不需要学习算法,但在我看来并不是这样的,我觉得算法思维也是一个程序员重要的“内功”,良好的算法思维可以让我们写出更好的代码,所以算法是每个程序员进阶必须学习的。
题目描述
给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。
示例
示例1
输入:points = [[1,1],[2,2],[3,3]]
输出:3
示例2
输入: points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出: 4
提示:
- 1 <= points.length <= 300
- points[i].length == 2
- -104 <= xi, yi <= 104
- points 中的所有点 互不相同
思路
看完题目描述和所给出的示例,我们了解了题目的要求,题目是想要我们计算出所给的坐标中可以连成一条直线的点数最多有多少个点,了解了题意后我们可以开始思考解题思路。
暴力解法
看了题目提示的数据量只有300,并不是很大的数据量,所以我们完全可以进行暴力枚举,找出所有可以组成一条直线的点,并找出最大值即可。
- 两点确定一条直线 我们都知道两个点就可以确定一条直线,所以我们只需要找出两个点来确定一条直线,然后再找出剩下在这条直线上的所有点,但枚举完所有直线点数最大值即为题目结果。
- 斜率判断是否在直线上 直接通过斜率来判断是不可以的,因为斜率相等的两条直线存在两种情况:要么平行,要么重合。我们应该要排除平行这种情况的干扰,可以这样做,我们可以取原本确定一条直线的某一个点,加上另外一个新的点,如果这两个点的斜率与原本确定直线的斜率相等,则可以说明该点也在这条直线上。具体代码如下:
完整代码
/**
* @param {number[][]} points
* @return {number}
*/
var maxPoints = function(points) {
let n = points.length;
let ans = 1;
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
let x = points[i],y = points[j],cnt = 2;
for (let k = j + 1; k < n; k++) {
let p = points[k];
let s1 = (y[1] - x[1]) * (p[0] - y[0]);
let s2 = (p[1] - y[1]) * (y[0] - x[0]);
if (s1 == s2) cnt++;
}
ans = Math.max(ans, cnt);
}
}
return ans;
};