Count maximum points on same line

• Difficulty Level : Hard
• Last Updated : 01 Sep, 2021

Given N point on a 2D plane as pair of (x, y) co-ordinates, we need to find maximum number of point which lie on the same line.
Examples:

Input : points[] = {-1, 1}, {0, 0}, {1, 1},
{2, 2}, {3, 3}, {3, 4}
Output : 4
Then maximum number of point which lie on same
line are 4, those point are {0, 0}, {1, 1}, {2, 2},
{3, 3}

Recommended: Please solve it on “PRACTICE” first, before moving on to the solution.

We can solve above problem by following approach – For each point p, calculate its slope with other points and use a map to record how many points have same slope, by which we can find out how many points are on same line with p as their one point. For each point keep doing the same thing and update the maximum number of point count found so far.
Some things to note in implementation are:
1) if two point are (x1, y1) and (x2, y2) then their slope will be (y2 – y1) / (x2 – x1) which can be a double value and can cause precision problems. To get rid of the precision problems, we treat slope as pair ((y2 – y1), (x2 – x1)) instead of ratio and reduce pair by their gcd before inserting into map. In below code points which are vertical or repeated are treated separately.
2) If we use unordered_map in c++ or HashMap in Java for storing the slope pair, then total time complexity of solution will be O(n^2)

C++

 /* C/C++ program to find maximum number of pointwhich lie on same line */#include #include  using namespace std; // method to find maximum collinear pointint maxPointOnSameLine(vector< pair > points){    int N = points.size();    if (N < 2)        return N;     int maxPoint = 0;    int curMax, overlapPoints, verticalPoints;     // here since we are using unordered_map    // which is based on hash function    //But by default we don't have hash function for pairs    //so we'll use hash function defined in Boost library    unordered_map, int,boost::              hash > > slopeMap;     // looping for each point    for (int i = 0; i < N; i++)    {        curMax = overlapPoints = verticalPoints = 0;         // looping from i + 1 to ignore same pair again        for (int j = i + 1; j < N; j++)        {            // If both point are equal then just            // increase overlapPoint count            if (points[i] == points[j])                overlapPoints++;             // If x co-ordinate is same, then both            // point are vertical to each other            else if (points[i].first == points[j].first)                verticalPoints++;             else            {                int yDif = points[j].second - points[i].second;                int xDif = points[j].first - points[i].first;                int g = __gcd(xDif, yDif);                 // reducing the difference by their gcd                yDif /= g;                xDif /= g;                 // increasing the frequency of current slope                // in map                slopeMap[make_pair(yDif, xDif)]++;                curMax = max(curMax, slopeMap[make_pair(yDif, xDif)]);            }             curMax = max(curMax, verticalPoints);        }         // updating global maximum by current point's maximum        maxPoint = max(maxPoint, curMax + overlapPoints + 1);         // printf("maximum collinear point        // which contains current point        // are : %d\n", curMax + overlapPoints + 1);        slopeMap.clear();    }     return maxPoint;} // Driver codeint main(){    const int N = 6;    int arr[N] = {{-1, 1}, {0, 0}, {1, 1}, {2, 2},                    {3, 3}, {3, 4}};     vector< pair > points;    for (int i = 0; i < N; i++)        points.push_back(make_pair(arr[i], arr[i]));     cout << maxPointOnSameLine(points) << endl;     return 0;}

Python3

 def maxPoints(points):        n=len(points)         # upto two points all points will be part of the line        if n<3:            return n         max_val=0         # looping for each point        for i in points:             # Creating a dictionary for every new            # point to save memory            d = {}            dups = 0            cur_max = 0             # pairing with all other points            for j in points:                if i!=j:                    if j==i: #vertical line                        slope='inf'                    else:                        slope=float(j-i)/float(j-i)                     # Increasing the frequency of slope and                    # updating cur_max for current point(i)                    d[slope] = d.get(slope,0)+1                    cur_max=max(cur_max, d[slope])                 # if both points are equal same increase                # duplicates count.                # Please note that this will also increment                # when we map it with itself.                # we still do it because we will not have to                # add the extra one at the end.                else:                    dups+=1             max_val=max(max_val, cur_max+dups)         return max_val # Driver codepoints = [(-1, 1), (0, 0), (1, 1), (2, 2), (3, 3), (3, 4)]print(maxPoints(points))

This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.