Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

**Analysis**

This problem can be solve by counting points that have the same slope for each point. When counting, we need to be careful about the duplicate points and points on the vertical lines.

**Java Solution**

public int maxPoints(Point[] points) { if(points == null || points.length == 0) return 0; HashMap<Double, Integer> result = new HashMap<Double, Integer>(); int max=0; for(int i=0; i<points.length; i++){ int duplicate = 1;// int vertical = 0; for(int j=i+1; j<points.length; j++){ //handle duplicates and vertical if(points[i].x == points[j].x){ if(points[i].y == points[j].y){ duplicate++; }else{ vertical++; } }else{ double slope = points[j].y == points[i].y ? 0.0 : (1.0 * (points[j].y - points[i].y)) / (points[j].x - points[i].x); if(result.get(slope) != null){ result.put(slope, result.get(slope) + 1); }else{ result.put(slope, 1); } } } for(Integer count: result.values()){ if(count+duplicate > max){ max = count+duplicate; } } max = Math.max(vertical + duplicate, max); result.clear(); } return max; } |

The relation between normal cases, vertical cases and duplicate cases can be shown as follows:

this fails for [[0,0],[94911151,94911150],[94911152,94911151]]

Because the point itself is counted in duplicate. Otherwise, the point would not be counted in the line based on itself.

This will work also when two lines are parallel. Notice that the hashmap is deleted for each point, therefore saving the slopes is only valid to the current point we are looking at

Why should the “duplicate” variable be initialized “1” instead of “0”?

Valid point.. has anyone found solution to parallel lines case?

This solution is not right. As Aditya and AR pointed out below. Just comparing slop is not enough ..also double as key will not work as well ?

What happens when two lines are parallel. They have the same slope but are not collinear?

the coursera course by princeton “Algorithms: I” by Sedgewick has this as its 2nd programming assignment, and the correct solution is O(n^2 lg n) but also outputs a list of vectors of the collinear line segments, not just counting the # of points in a line

This is clearly wrong. If you are storing the slope as a double you might never get a match for certain cases. We should store it in fractional form of p/q.

I believe time complexity here is O(n^3). Can we reduce it to O(n^2)?

what is the “1.0” for? I forgot this part the it stuck at 20/27 test case.

double slope = points[j].y == points[i].y ? 0.0

: (1.0 * (points[j].y - points[i].y))

/ (points[j].x - points[i].x);

When there is no match for result.get(slope), you better initialize with 2: result.put(slope, 2);

There is at least 2 points for each line.