leetcode 149. Max Points on a Line

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;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值