LintCode 最多有多少个点在一条直线上

题目

给出二维平面上的n个点,求最多有多少点在同一条直线上。

样例

给出4个点:(1, 2), (3, 6), (0, 0), (1, 3)。
一条直线上的点最多有3个。

解决思路

  1. 重复的点没有必要去增加时间复杂度, 先把point点简化成没有重复的新数组norepeatvalues以及记录每个新数组的成员point对应的重复次数repeatcounts数组;
  2. 两个点可以确定一条直线,假设有一个起始点Point[i]和Point[j],它们俩相连的斜率为k,其它只要和它们相连的点必定与它们在同一条直线上;当然,斜率不存在的极端情况也是要考虑在内的,斜率不存在的点,它们点X坐标必定一样;
  3. 假设(1,3),(2,6),(3,9);有三个(1,3)的重复点,则norepeatvalues成员为[(1,3),(2,6),(3,9)],对应的点重复的个数数组为[2,0,0],在一条直线上的点共有3+2+0+0=5个;
  4. 由于norepeatvalues的长度和对应的点重复的个数数组repeatcounts长度不定,所以采用ArrayList数组;

核心算法

/**
 * 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 {
    /**
     * @param points an array of point
     * @return an integer
     */
    public int maxPoints(Point[] points) {
        // Write your code here
        if(points==null){
           return 0;
       }
       int maxcount=0;
       int len=points.length;
       if(len<2){
           return len;
       }
       ArrayList<Point>norepeatvalues=new ArrayList<Point>();//简化数组,记录不重复的数组
       ArrayList<Integer>repeatcounts=new ArrayList<Integer>();//简化数组,记录norepeatvalues.get[i]的元素对应的在Point数组里面拥有的元素的重复个数
       for(int i=0;i<len;i++){
           int repeatcount=0;
           boolean isrepeatnum=false;
          for(int m=0;m<norepeatvalues.size();m++){
              //判断这个Point是否是记录已经存在的
              if(norepeatvalues.get(m).x==points[i].x&&points[i].y==norepeatvalues.get(m).y){
                  isrepeatnum=true;
                  break;
              }
          }
          if(!isrepeatnum){
            //这个Point不是norepeatvalues记录已经存在的,则继续
              for(int j=i+1;j<len;j++){
                   if(points[i].x==points[j].x&&points[i].y==points[j].y){
                       //repeatcounts数组记录有多少个和points[i]相同的点
                       repeatcount++;
                   }
               }
               norepeatvalues.add(points[i]);
               repeatcounts.add(repeatcount);
          }

       }
       len=norepeatvalues.size();
       if(len==1){
           //如果只有一个非重复元素
           return len+repeatcounts.get(0);
       }

       for(int i=0;i<len-1;i++){
           for(int j=i+1;j<len;j++){
               int tempcount=2+repeatcounts.get(i)+repeatcounts.get(j);
               float k=0f;
               boolean hasK=true;//判断斜率是否存在
               if(norepeatvalues.get(i).x==norepeatvalues.get(j).x){
                   hasK=false;
               }else{
                  k=(float)(norepeatvalues.get(i).y-norepeatvalues.get(j).y)/(norepeatvalues.get(i).x-norepeatvalues.get(j).x);
               }

               float b=norepeatvalues.get(i).y-k*norepeatvalues.get(i).x;
               for(int m=j+1;m<len;m++){
                   if(hasK){
                       //斜率存在
                       float curk=(float)(norepeatvalues.get(i).y-norepeatvalues.get(m).y)/(norepeatvalues.get(i).x-norepeatvalues.get(m).x);
                       //System.out.println("当前斜率为"+curk);
                       if(curk==k){
                           tempcount=tempcount+repeatcounts.get(m)+1;
                       }
                   }else{
                     //斜率不存在
                       if(norepeatvalues.get(i).x==norepeatvalues.get(m).x){
                           tempcount=tempcount+repeatcounts.get(m)+1;
                       }
                   }

               }
               if(tempcount>maxcount){
                   maxcount=tempcount;
                //   if(maxcount==26){
                //     //System.out.println("当前斜率为"+k);
                //     //System.out.println("当前为第"+i+"个");
                //     //System.out.println("当前起始点的x为&&&"+norepeatvalues.get(i).x+"&&&&当前起始点的y为"+norepeatvalues.get(i).y);

                //   }
               }
           }
       }
       return maxcount;
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值