意思:在一个二维平面上有n个点,求出现在同一直线上的点(就是那n个点)的最大个数。
尝试一
结果:case通过率为7.69%
代码:
/**
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
/**
* 思路:1.for循环求直线
* 2.for循环判断点是否在该直线上
* @param points
* @return
*/
public int maxPoints(Point[] points) {
/*特殊情况处理*/
if(points==null ){
return 0;
}
if(points.length==1){
return 1;
}
boolean[] marks=new boolean[points.length];
int max=0;
for(int i=0;i<points.length;++i){
for(int j=(i+1)%points.length;j!=i;++j){
if(marks[j]==true){
continue;
}
/* 开始连线*/
int count=0;
if(points[i].x==points[j].x){/*特殊情况:斜率不存在*/
for(int z=0;z<points.length;++z){
if(points[z].x==points[i].x){
count++;
}
}
if(count>max){
max=count;
}
}else{/*一般情况,斜率存在*/
//斜率应该用double来存
double k;
if(points[i].y-points[j].y==0){
k=0;
}else {
k=1.0*(points[i].y - points[j].y) / (points[i].x - points[j].x);
}
double b=points[i].y - (k*points[i].x);
/*for循环确定该线(斜率存在)上的点的个数*/
for(int z=0;z<points.length;++z){
if(k*points[z].x+b-points[z].y < 1e-12){
count++;
}
}
if(count>max){
max=count;
}
}
}
//当point[i]与其他点的所有联系情况都尝试过了,就表明这个点不可用了
marks[i]=true;
}
return max;
}
}
测试用例:
不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为7.69%
用例:
[(0,0),(0,0)]
对应输出应该为:
2
你的输出为:
java.lang.ArrayIndexOutOfBoundsException: 2
分析:没想到竟然可以存在重复的点。
尝试2
结果:答案正确:恭喜!您提交的程序通过了所有的测试用例
代码:
import java.util.*;
/**
* Definition for a point.
* class Point {
* int x;
* int y;
* Point() { x = 0; y = 0; }
* Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
/**
* 思路:1.for循环求直线
* 2.for循环判断点是否在该直线上
* @param points
* @return
*/
public int maxPoints(Point[] points) {
/*特殊情况处理*/
if(points==null || points.length==0 ){
return 0;
}
/*todo 去重*/
Arrays.sort(points, new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
if(o1.x==o2.x && o1.y==o2.y){
return 0;
}else if(o1.x*o1.x+o1.y*o1.y>o2.x*o2.x+o2.y*o2.y){
return 1;
}else{
return -1;
}
}
});
ArrayList<Point> pA=new ArrayList<>();
pA.add(points[0]);
for(int i=1;i<points.length;++i){
if(points[i].x==points[i-1].x && points[i].y==points[i-1].y){
continue;
}
pA.add(points[i]);
}
/*另一种特殊情况,全为重复点*/
if(pA.size()==1){
return points.length;
}
boolean[] marks=new boolean[pA.size()];
int max=0;
for(int i=0;i<pA.size();++i){
for(int j=(i+1)%pA.size();j!=i;j=(++j)%pA.size()){
if(marks[j]==true){
continue;
}
/* 开始连线*/
int count=0;
if(pA.get(i).x==pA.get(j).x){/*特殊情况:斜率不存在*/
for(int z=0;z<points.length;++z){
if(points[z].x==pA.get(i).x){
count++;
}
}
if(count>max){
max=count;
}
}else{/*一般情况,斜率存在*/
//斜率应该用double来存
double k;
if(pA.get(i).y-pA.get(j).y==0){
k=0;
}else {
k=1.0*(pA.get(i).y - pA.get(j).y) / (pA.get(i).x - pA.get(j).x);
}
double b=pA.get(i).y - (k*pA.get(i).x);
/*for循环确定该线(斜率存在)上的点的个数*/
for(int z=0;z<points.length;++z){
if(Math.abs( k*points[z].x+b-points[z].y) < 1e-12){
count++;
}
}
if(count>max){
max=count;
}
}
}
//当point[i]与其他点的所有联系情况都尝试过了,就表明这个点不可用了
marks[i]=true;
}
return max;
}
}
结论
- 一个数组,从第i位开始遍历(但不报第i位)。初识循环变量时与循环变量增加时分别取余:
int p[]={1,2,3,5};
int i=2;
for(int j=(i+1)%p.length;j!=i;j=(++j)%p.length){
}
- double比较大小是不能用a==b,而是a-b<1e-12。
- double判断是否为0,要
Math.abs( k*points[z].x+b-points[z].y) < 1e-12
。要取绝对值 - double能够精确到15位。参考 Java中float/double取值范围与精度