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

来源:互联网 发布:spc蜗牛面膜怎么样知乎 编辑:程序博客网 时间:2024/05/02 02:41

题目

给出二维平面上的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;    }}
1 0