您的位置:首页 > 其它

Leetcode-Max Points on a Line

2014-12-16 06:00 525 查看
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

A better solution:

/**
* Definition for a point.
* class Point {
*     int x;
*     int y;
*     Point() { x = 0; y = 0; }
*     Point(int a, int b) { x = a; y = b; }
* }
*/
class Line{
//a/b = (y1-y2)/(x1-x2), c/d=(x1y2-x2y1)/(x1-x2)
int a, b, c, d;
String uid;
Set<Point> pList;
public Line(Point p1, Point p2){
pList = new HashSet<Point>();
a = p1.y-p2.y;
b = p1.x-p2.x;
c = p1.x*p2.y-p2.x*p1.y;
d = p1.x - p2.x;

if (a==0){
a = 0;
b = 1;
c = p1.y;
d = 1;
} else if (b==0){
a = 1;
b = 0;
c = p1.x;
d = 1;
} else {
int gcd = getGCD(a,b);
a = a/gcd;
b = b/gcd;
if (b<0 && a>0){
a = -a;
b = -b;
}
gcd = getGCD(c,d);
c = c/gcd;
d = d/gcd;
if (d<0 && c>0){
c = -c;
d = -d;
}
}
//generate uid
setUID();
}

public void setUID(){
uid = a + "/" + b + "/" + c + "/" + d;
}

public String getUID(){
return uid;
}

private int getGCD(int x, int y){
while (y!=0){
int val = x % y;
x = y;
y = val;
}
return x;
}
}

public class Solution {
public int maxPoints(Point[] points) {
if (points.length<3) return points.length;

int res = 0;
Map<Point,Integer> pMap = new HashMap<Point,Integer>();
for (int i=0;i<points.length;i++)
if (pMap.containsKey(points[i])){
pMap.put(points[i],pMap.get(points[i])+1);
} else {
pMap.put(points[i],1);
}

Map<String,Line> lineMap = new HashMap<String,Line>();
Iterator iter1 = pMap.entrySet().iterator();
while (iter1.hasNext()){
Map.Entry en1 = (Map.Entry) iter1.next();
int val = (int) en1.getValue();
if (res<val) res = val;
Point p1 = (Point) en1.getKey();
Map<Point,Integer> pMap2 = new HashMap<Point,Integer>();
pMap2.putAll(pMap);
pMap2.remove(p1);
while (!pMap2.isEmpty()){
Iterator iter2 = pMap2.entrySet().iterator();
Map.Entry en2 = (Map.Entry) iter2.next();
Point p2 = (Point) en2.getKey();
Line l1 = new Line(p1,p2);
String uid = l1.getUID();
if (lineMap.containsKey(uid)){
Line l2 = lineMap.get(uid);
l2.pList.add(p1);
l2.pList.add(p2);
for (Point p: l2.pList)
pMap2.remove(p);
} else {
l1.pList.add(p1);
l1.pList.add(p2);
pMap2.remove(p2);
lineMap.put(l1.getUID(),l1);
}
}
}

iter1 = lineMap.entrySet().iterator();
while (iter1.hasNext()){
Map.Entry en = (Map.Entry) iter1.next();
Line l1 = (Line) en.getValue();
int pNum = 0;
for (Point p: l1.pList)
pNum += pMap.get(p);
if (res<pNum) res = pNum;
}
return res;
}
}


Solution:

/**
* Definition for a point.
* class Point {
*     int x;
*     int y;
*     Point() { x = 0; y = 0; }
*     Point(int a, int b) { x = a; y = b; }
* }
*/

class Line {
int slopeX;
int slopeY;
int b;
boolean negSlope;
boolean samePointLine;
Set<Point> pointSet;
String uid;
public Line(int sx, int sy, int bb,boolean spl){
if (sx<0) slopeX = -sx;
else slopeX = sx;

if (sy<0) slopeY = -sy;
else slopeY = sy;

if (sy==0) slopeX=1;
if (sx==0) slopeY=1;
b = bb;

if (sx<0 || sy<0) negSlope = true;
else negSlope = false;

samePointLine = spl;

pointSet = new HashSet<Point>();

uid = Integer.toString(slopeX)+"/"+Integer.toString(slopeY)+"/"+Double.toString(b)+"/"+Boolean.toString(negSlope)+"/"+Boolean.toString(samePointLine);
}

public boolean equals(Line l2){
if (uid==l2.uid)
return true;
else return false;
}

}

public class Solution {
public int maxPoints(Point[] points) {
if (points.length==1) return 1;

Set<Point> pSet = new HashSet<Point>();
for (int i=0;i<points.length;i++) pSet.add(points[i]);

Map<String,Line> lineList = new HashMap<String,Line>();
List<String> uidList = new ArrayList<String>();
for (int i=1;i<points.length;i++){
Set<Point> curPSet = new HashSet<Point>();
curPSet.addAll(pSet);
for (int j=0;j<i;j++)
if (curPSet.contains(points[j])){
//This point has not been checked.
//Calculate the line formed by i and j
int ix = points[i].x;
int iy = points[i].y;
int jx = points[j].x;
int jy = points[j].y;
int sx = points[i].x-points[j].x;
int sy = points[i].y-points[j].y;
Line l1 = null;
//infnite slope line.
if (sx==0 && sy==0)
l1 = new Line(points[i].x,points[i].y,0,true);
else if (sx==0)
l1 = new Line(0,1,points[i].x,false);
else if (sy==0)
l1 = new Line(1,0,points[i].y,false);
else {
int bb = jy*ix-jx*iy;
int gcd = getGCD(sx,sy);
int gcd2 = getGCD(bb,sx);
sx = sx/gcd;
sy = sy/gcd;
bb = bb/gcd2;
l1 = new Line(sx,sy,bb,false);
}

//Check each exsiting line.
if (lineList.containsKey(l1.uid)){
lineList.get(l1.uid).pointSet.add(points[i]);
lineList.get(l1.uid).pointSet.add(points[j]);
curPSet.removeAll(lineList.get(l1.uid).pointSet);

} else {
lineList.put(l1.uid,l1);
uidList.add(l1.uid);
l1.pointSet.add(points[i]);
l1.pointSet.add(points[j]);
}
}
}

int max = 0;
for (int i=0;i<uidList.size();i++)
if (lineList.get(uidList.get(i)).pointSet.size()>max)
max = lineList.get(uidList.get(i)).pointSet.size();

return max;

}

public int getGCD(int a, int b){
int left = a%b;
while (left!=0){
a=b;
b=left;
left=a%b;
}
return b;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: