GFG App
Open App
Browser
Continue

# Count maximum points on same line

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 Practice

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) and space complexity will be O(n).

Implementation:

## C++

 `/* C/C++ program to find maximum number of point` `which lie on same line */` `#include ` `#include `   `using` `namespace` `std;`   `// method to find maximum collinear point` `int` `maxPointOnSameLine(vector< pair<``int``, ``int``> > 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 code` `int` `main()` `{` `    ``const` `int` `N = 6;` `    ``int` `arr[N][2] = {{-1, 1}, {0, 0}, {1, 1}, {2, 2},` `                    ``{3, 3}, {3, 4}};`   `    ``vector< pair<``int``, ``int``> > points;` `    ``for` `(``int` `i = 0; i < N; i++)` `        ``points.push_back(make_pair(arr[i][0], arr[i][1]));`   `    ``cout << maxPointOnSameLine(points) << endl;`   `    ``return` `0;` `}`

## Java

 `/* Java program to find maximum number of point` `which lie on same line */` `import` `java.util.*;`   `class` `GFG {` `    ``static` `int` `gcd(``int` `p, ``int` `q)` `    ``{` `        ``if` `(q == ``0``) {` `            ``return` `p;` `        ``}` `        ``int` `r = p % q;` `        ``return` `gcd(q, r);` `    ``}`   `    ``static` `int` `N = ``6``;`   `    ``// method to find maximum collinear point` `    ``static` `int` `maxPointOnSameLine(``int``[][] points)` `    ``{` `        ``if` `(N < ``2``)` `            ``return` `N;` `        ``int` `maxPoint = ``0``;` `        ``int` `curMax, overlapPoints, verticalPoints;`   `        ``HashMap slopeMap = ``new` `HashMap<>();` `        ``// 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][``0``] == points[j][``0``]` `                    ``&& points[i][``1``] == points[j][``1``])` `                    ``overlapPoints++;`   `                ``// If x co-ordinate is same, then both` `                ``// point are vertical to each other` `                ``else` `if` `(points[i][``0``] == points[j][``0``])` `                    ``verticalPoints++;`   `                ``else` `{` `                    ``int` `yDif = points[j][``1``] - points[i][``1``];` `                    ``int` `xDif = points[j][``0``] - points[i][``0``];` `                    ``int` `g = gcd(xDif, yDif);`   `                    ``// reducing the difference by their gcd` `                    ``yDif /= g;` `                    ``xDif /= g;`   `                    ``// Convert the pair into a string to use` `                    ``// as dictionary key` `                    ``String pair = (yDif) + ``" "` `+ (xDif);` `                    ``if` `(!slopeMap.containsKey(pair))` `                        ``slopeMap.put(pair, ``0``);`   `                    ``// increasing the frequency of current` `                    ``// slope in map` `                    ``slopeMap.put(pair,` `                                 ``slopeMap.get(pair) + ``1``);` `                    ``curMax = Math.max(curMax,` `                                      ``slopeMap.get(pair));` `                ``}`   `                ``curMax = Math.max(curMax, verticalPoints);` `            ``}`   `            ``// updating global maximum by current point's` `            ``// maximum` `            ``maxPoint = Math.max(maxPoint,` `                                ``curMax + overlapPoints + ``1``);` `            ``slopeMap.clear();` `        ``}`   `        ``return` `maxPoint;` `    ``}`   `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int` `points[][] = { { -``1``, ``1` `}, { ``0``, ``0` `}, { ``1``, ``1` `},` `                           ``{ ``2``, ``2` `},  { ``3``, ``3` `}, { ``3``, ``4` `} };` `        ``System.out.println(maxPointOnSameLine(points));` `    ``}` `}`

## Python3

 `# python3 program to find maximum number of 2D points that lie on the same line.`   `from` `collections ``import` `defaultdict` `from` `math ``import` `gcd` `from` `typing ``import` `DefaultDict, ``List``, ``Tuple`   `IntPair ``=` `Tuple``[``int``, ``int``]`     `def` `normalized_slope(a: IntPair, b: IntPair) ``-``> IntPair:` `    ``"""` `    ``Returns normalized (rise, run) tuple. We won't return the actual rise/run` `    ``result in order to avoid floating point math, which leads to faulty` `    ``comparisons.`   `    ``See` `    ``https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems` `    ``"""` `    ``run ``=` `b[``0``] ``-` `a[``0``]`   `    ``# normalize undefined slopes to (1, 0)` `    ``if` `run ``=``=` `0``:` `        ``return` `(``1``, ``0``)`   `    ``# normalize to left-to-right` `    ``if` `run < ``0``:` `        ``a, b ``=` `b, a` `        ``run ``=` `b[``0``] ``-` `a[``0``]`   `    ``rise ``=` `b[``1``] ``-` `a[``1``]` `    ``# Normalize by greatest common divisor.` `    ``# math.gcd only works on positive numbers.` `    ``gcd_ ``=` `gcd(``abs``(rise), run)` `    ``return` `(` `        ``rise ``/``/` `gcd_,` `        ``run ``/``/` `gcd_,` `    ``)`     `def` `maximum_points_on_same_line(points: ``List``[``List``[``int``]]) ``-``> ``int``:` `    ``# You need at least 3 points to potentially have non-collinear points.` `    ``# For [0, 2] points, all points are on the same line.` `    ``if` `len``(points) < ``3``:` `        ``return` `len``(points)`   `    ``# Note that every line we find will have at least 2 points.` `    ``# There will be at least one line because len(points) >= 3.` `    ``# Therefore, it's safe to initialize to 0.` `    ``max_val ``=` `0`   `    ``for` `a_index ``in` `range``(``0``, ``len``(points) ``-` `1``):` `        ``# All lines in this iteration go through point a.` `        ``# Note that lines a-b and a-c cannot be parallel.` `        ``# Therefore, if lines a-b and a-c have the same slope, they're the same` `        ``# line.` `        ``a ``=` `tuple``(points[a_index])` `        ``# Fresh lines already have a, so default=1` `        ``slope_counts: DefaultDict[IntPair, ``int``] ``=` `defaultdict(``lambda``: ``1``)`   `        ``for` `b_index ``in` `range``(a_index ``+` `1``, ``len``(points)):` `            ``b ``=` `tuple``(points[b_index])` `            ``slope_counts[normalized_slope(a, b)] ``+``=` `1`   `        ``max_val ``=` `max``(` `            ``max_val,` `            ``max``(slope_counts.values()),` `        ``)`   `    ``return` `max_val`     `print``(maximum_points_on_same_line([` `    ``[``-``1``, ``1``],` `    ``[``0``, ``0``],` `    ``[``1``, ``1``],` `    ``[``2``, ``2``],` `    ``[``3``, ``3``],` `    ``[``3``, ``4``],` `]))`   `# This code is contributed by Jose Alvarado Torre`

## C#

 `/* C# program to find maximum number of point` `which lie on same line */` `using` `System;` `using` `System.Collections.Generic;`   `class` `GFG {`   `  ``static` `int` `gcd(``int` `p, ``int` `q)` `  ``{` `    ``if` `(q == 0) {` `      ``return` `p;` `    ``}`   `    ``int` `r = p % q;`   `    ``return` `gcd(q, r);` `  ``}`   `  ``static` `int` `N = 6;`   `  ``// method to find maximum collinear point` `  ``static` `int` `maxPointOnSameLine(``int``[, ] points)` `  ``{` `    ``if` `(N < 2)` `      ``return` `N;`   `    ``int` `maxPoint = 0;` `    ``int` `curMax, overlapPoints, verticalPoints;`   `    ``Dictionary<``string``, ``int``> slopeMap` `      ``= ``new` `Dictionary<``string``, ``int``>();`   `    ``// 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, 0] == points[j, 0]` `            ``&& points[i, 1] == points[j, 1])` `          ``overlapPoints++;`   `        ``// If x co-ordinate is same, then both` `        ``// point are vertical to each other` `        ``else` `if` `(points[i, 0] == points[j, 0])` `          ``verticalPoints++;`   `        ``else` `{` `          ``int` `yDif = points[j, 1] - points[i, 1];` `          ``int` `xDif = points[j, 0] - points[i, 0];` `          ``int` `g = gcd(xDif, yDif);`   `          ``// reducing the difference by their gcd` `          ``yDif /= g;` `          ``xDif /= g;`   `          ``// Convert the pair into a string to use` `          ``// as dictionary key` `          ``string` `pair = Convert.ToString(yDif)` `            ``+ ``" "` `            ``+ Convert.ToString(xDif);` `          ``if` `(!slopeMap.ContainsKey(pair))` `            ``slopeMap[pair] = 0;`   `          ``// increasing the frequency of current` `          ``// slope in map` `          ``slopeMap[pair]++;` `          ``curMax` `            ``= Math.Max(curMax, slopeMap[pair]);` `        ``}`   `        ``curMax = Math.Max(curMax, verticalPoints);` `      ``}`   `      ``// updating global maximum by current point's` `      ``// maximum` `      ``maxPoint = Math.Max(maxPoint,` `                          ``curMax + overlapPoints + 1);` `      ``slopeMap.Clear();` `    ``}`   `    ``return` `maxPoint;` `  ``}`   `  ``// Driver code` `  ``public` `static` `void` `Main(``string``[] args)` `  ``{`   `    ``int``[, ] points = { { -1, 1 }, { 0, 0 }, { 1, 1 },` `                      ``{ 2, 2 },  { 3, 3 }, { 3, 4 } };`   `    ``Console.WriteLine(maxPointOnSameLine(points));` `  ``}` `}`   `// This code is contributed by phasing17`

## Javascript

 `/* JavaScript program to find maximum number of point` `which lie on same line */`   `// Function to find gcd of two numbers` `let gcd = ``function``(a, b) {` `  ``if` `(!b) {` `    ``return` `a;` `  ``}` `  ``return` `gcd(b, a % b);` `}`   `// method to find maximum collinear point` `function` `maxPointOnSameLine(points){` `    ``let N = points.length;` `    ``if` `(N < 2){` `        ``return` `N;` `    ``}        `   `    ``let maxPoint = 0;` `    ``let curMax, overlapPoints, verticalPoints;`   `    ``// Creating a map for storing the data. ` `    ``let slopeMap = ``new` `Map();`   `    ``// looping for each point` `    ``for` `(let i = 0; i < N; i++)` `    ``{` `        ``curMax = 0;` `        ``overlapPoints = 0;` `        ``verticalPoints = 0;` `        `  `        ``// looping from i + 1 to ignore same pair again` `        ``for` `(let 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][0] === points[j][0]){` `                ``verticalPoints++;` `            ``}` `            ``else``{` `                ``let yDif = points[j][1] - points[i][1];` `                ``let xDif = points[j][0] - points[i][0];` `                ``let g = gcd(xDif, yDif);`   `                ``// reducing the difference by their gcd` `                ``yDif = Math.floor(yDif/g);` `                ``xDif = Math.floor(xDif/g);` `                `  `                ``// increasing the frequency of current slope. ` `                ``let tmp = [yDif, xDif];` `                ``if``(slopeMap.has(tmp.join(``''``))){` `                    ``slopeMap.set(tmp.join(``''``), slopeMap.get(tmp.join(``''``)) + 1);` `                ``}` `                ``else``{` `                    ``slopeMap.set(tmp.join(``''``), 1);` `                ``}` `                `  `                ``curMax = Math.max(curMax, slopeMap.get(tmp.join(``''``)));` `            ``}` `            `  `            ``curMax = Math.max(curMax, verticalPoints);` `        ``}`   `        ``// updating global maximum by current point's maximum` `        ``maxPoint = Math.max(maxPoint, curMax + overlapPoints + 1);` `        `  `        ``// printf("maximum collinear point` `        ``// which contains current point` `        ``// are : %d\n", curMax + overlapPoints + 1);` `        ``slopeMap.clear();` `    ``}` `   `  `    ``return` `maxPoint;` `}`   `// Driver code` `{` `    ``let N = 6;` `    ``let arr = [[-1, 1], [0, 0], [1, 1], [2, 2],` `                    ``[3, 3], [3, 4]];`   `    ``console.log(maxPointOnSameLine(arr));` `}`   `// The code is contributed by Gautam goel (gautamgoel962)`

Output

`4`

Time Complexity: O(n2logn), where n denoting length of string.
Auxiliary Space: O(n).

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.

My Personal Notes arrow_drop_up