Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
法一:两点确定一条直线(两两组合),然后在判断其他点是否在这条直线上,O(n^3)
法二:遍历每一个点i {其他点j与该点i组成直线的斜率xl,斜率相同,统计加1----斜率相同又过同一个点i,那么他们一定在同一条直线上}
但是要注意,与i点重复的点。(0.0/-1 的结果转成string是-0.0;0.0/1的结果是0.0,他们两做key是不同的key
)
/**
* 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 {
public int maxPoints(Point[] points) {
int ret=0;
for(int i=0;i<points.length;i++){
Map<Double,Integer> map=new HashMap<Double,Integer>();//过i点的直线的斜率-key
int count=1;//与i点重合的点,它自身算一个
for(int j=i+1;j<points.length;j++){
double dx=points[j].x-points[i].x;
double dy=points[j].y-points[i].y;
Double xl=0.0;
if(dx==0){
if(dy!=0) xl=Double.MAX_VALUE;
else {
count++;//重复点 ,没有斜率后面不用算了。
continue;
}
}
else
xl= dy==0?0:dy/dx;//这里不能少!!!!! 同时要注意0/-1 与0/1 做key是不同的key,[[2,3],[3,3],[-5,3]] 0.0与-0.0 map中key不是不一样的
if (!map.containsKey(xl)) {
map.put(xl, 1);
}
else{
map.put(xl, map.get(xl)+1);
}
}
ret=ret<count?count:ret; //只有一个点的时候,下面for循环没有执行,ret等于0.所以要加这一句
System.out.println("count="+count);
//一定要最后来统计最大值,因为如果后面的都是重复点呢,count一直加加呢
for (double key : map.keySet()) {
System.out.println(key+"="+map.get(key));
ret = Math.max((count + map.get(key)), ret);
}
}
return ret;
}
}
改进:
用tmpMax 记录过某点i 的最多
点的个数(不包括重复的i点),最后遍历完了,再加上重复个数count。。这样就不需遍历map了
/**
* 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 {
public int maxPoints(Point[] points) {
int ret=0;
for(int i=0;i<points.length;i++){
Map<Double,Integer> map=new HashMap<Double,Integer>();//过i点的直线的斜率-key
int tmpMax=0;
int count=1;//与i点重合的点,它自身算一个
for(int j=i+1;j<points.length;j++){
double dx=points[j].x-points[i].x;
double dy=points[j].y-points[i].y;
Double xl=0.0;
if(dx==0){
if(dy!=0) xl=Double.MAX_VALUE;
else {
count++;//重复点 ,没有斜率后面不用算了。
continue;
}
}
else
xl= dy==0?0:dy/dx;//这里不能少!!!!! 同时要注意0/-1 与0/1 做key是不同的key,[[2,3],[3,3],[-5,3]] 0.0与-0.0 map中key不是不一样的
if (!map.containsKey(xl)) {
map.put(xl, 1);
}
else{
map.put(xl, map.get(xl)+1);
}
tmpMax=tmpMax<map.get(xl)?map.get(xl):tmpMax;//不算重复点时,过此点 的直线上的 最大点数
}
tmpMax+=count;
ret=ret<tmpMax?tmpMax:ret;
}
return ret;
}
}