题目: 149. 直线上最多的点数
解题思路
暴力解法:
枚举两个点构成的直线中,其余点在该直线上的个数,返回个数最大的情况
判断点p
是否在由start
和end
构成的直线上:
p
分别与start
和end
点的斜率是否相等
p [ 1 ] − s t a r t [ 1 ] p [ 0 ] − s t a r t [ 0 ] = p [ 1 ] − e n d [ 1 ] p [ 0 ] − e n d [ 0 ] \frac {p[1]-start[1]} {p[0]-start[0]}=\frac {p[1]-end[1]} {p[0]-end[0]} p[0]−start[0]p[1]−start[1]=p[0]−end[0]p[1]−end[1]- 为了防止除数为0的情况,可以将上述公式转换为:
( p [ 1 ] − s t a r t [ 1 ] ) ∗ ( p [ 0 ] − e n d [ 0 ] ) = ( p [ 1 ] − e n d [ 1 ] ) ∗ ( p [ 0 ] − s t a r t [ 0 ] ) ) (p[1]-start[1])*(p[0]-end[0])=(p[1]-end[1])*(p[0]-start[0])) (p[1]−start[1])∗(p[0]−end[0])=(p[1]−end[1])∗(p[0]−start[0]))
具体操作
- 一条直线可由两个点决定(
start
和end
) ans
记录最终答案,初始化为1 (至少有一个点在穿过它的直线上)- 逐次选择
start
和end
- 令
same
为余下所有点中,在该直线上的点的个数,初始化为2 (start
和end
已经在该直线上) - 逐次选择剩下的点,这里记为点
p
- 如果点
p
在该直线上,则same++
- 否则,选下一个点
- 如果点
- 该
start
和end
的情况遍历完毕,得到same
- 令
ans
选取目前为止最大的same
值- 继续循环或返回结果
代码
class Solution {
public int maxPoints(int[][] ps) {
int ans = 1;
for(int i=0; i<ps.length; i++){
for(int j=i+1; j<ps.length; j++){
int same = 2;
for(int k=j+1; k<ps.length; k++){
// start:第一个选择的点
int[] start = ps[i];
// end:第二个选择的点
int[] end = ps[j];
// p: 判断是否在start与end所在线上的点
int[] p = ps[k];
// p与start的斜率 与 p与end的斜率 如果相同,则在一条线上
/*
(p[1]-start[1]) / (p[0]-start[0]) = (p[1]-end[1]) / (p[0]-end[0])
为了防止除数为0的情况,可转化为
(p[1] - start[1]) * (p[0] - end[0]) = (p[1] - end[1]) * (p[0] - start[0])
*/
int s1 = (p[1] - start[1]) * (p[0] - end[0]);
int s2 = (p[1] - end[1]) * (p[0] - start[0]);
if(s1 == s2) same++;
}
ans = Math.max(same,ans);
}
}
return ans;
}
}