题目原型:
Given n points on a 2D plane, find the
maximum number of points that lie on the same straight line.
基本思路:
题目的意思就是找到一条直线,让最多的点在这条直线上,那么利用数学中的斜率定义,如果两个点与另外一个的斜率相等,那么这两个点与另外一个点在同一条直线上。
下面用到求最大公约数,注意:一个正数和一个负数求最大公约数是没意义的。
//通过斜率相等来求 public int maxPoints(Point[] points) { int maxSum = 0; if(points==null||points.length==0) return 0; //如果只有一个点时 if(points.length==1) return 1; //以一个点为基点,分别求出其余点与这个点之间斜率 for(int i = 0;i<points.length;i++) { int samePoint = 0; Map<String, Integer> map = new HashMap<String, Integer>(); int maxSumtmp = 0; for(int j = 0;j<points.length;j++) { if(i==j) continue; int x = points[j].x - points[i].x; int y = points[j].y - points[i].y; int tmp = gcd(Math.abs(x), Math.abs(y)); //两个点是同一点 if(tmp==0) { samePoint++; continue; } //我们的目标是表x变为正数,而当x变号了的话,为了保持斜率不变,那么y也应该变号 //如x=-1,y=-1,那么变为x=1,y=1;x=-1,y=1,那么变为x=1,y=-1; //此时我们就保证了以后比较map中key值时的不变形,如x=-1,y=-1和x=1,y=1的斜率相等,那么我们应该设置key值也相等,都为(1,1) if(x<0) { x = -x; y = -y; } //如果x和y中有一个为0,那么说明他们与x轴或y轴平行,那么斜率不存在正负 if(x==0||y==0) { x = Math.abs(x); y = Math.abs(y); } String str = "("+(x/tmp)+","+(y/tmp)+")"; if(map.keySet().contains(str)) map.put(str, map.get(str)+1); else map.put(str, 1); maxSumtmp = maxSumtmp>map.get(str)?maxSumtmp:map.get(str); } maxSum = Math.max(maxSumtmp+1+samePoint, maxSum); } return maxSum; } //最大公约数,如果最大公约数为0 ,说明这两个数为均为0 public int gcd(int a , int b) { return a==0?b:gcd(b%a, a); }
Max Points on a Line,布布扣,bubuko.com
原文:http://blog.csdn.net/cow__sky/article/details/21740653