Given two arrays x[] and y[] of points where (x[i], y[i]) represents a point on the x-y plane. Returns the maximum number of points that lie on the same straight line.
Examples:
Input: x[] = [1, 2, 3], y[] = [1, 2, 3]
Output: 3
Explanation: The points in straight line are- (1, 1), (2, 2) and (3, 3).
Input: x[] = [1, 3, 5, 4, 2, 1], y[] = [1, 2, 3, 1, 3, 4]
Output: 4
Explanation: The points in straight line are- (3, 2),(4, 1),(2, 3),(1, 4)
Table of Content
[Naive Approach] Brute Force Line Check - O(n³) Time and O(1) Space
Pick every pair of points to form a line, then count how many points lie on that line using cross product. Track maximum count across all pairs.
- If n ≤ 2, return n
- Initialize ans = 1
- For each pair (i, j), skip if points are identical
- For every other point k, check collinearity using cross product
- If (y[j] - y[i]) × (x[k] - x[i]) equals (y[k] - y[i]) × (x[j] - x[i]), increment count
- Update ans with maximum count
- Return ans
#include <iostream>
#include <vector>
using namespace std;
int maxPoints(vector<int>& x, vector<int>& y) {
int n = x.size();
// If there are 2 or fewer points,
// return the number of points
if (n <= 2)
return n;
int ans = 1;
// Iterate through each pair of points
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// Skip identical points
if (x[i] == x[j] && y[i] == y[j])
continue;
int cnt = 0;
// Check other points to see if they lie on the same line
for (int k = 0; k < n; k++) {
long long lhs =
1LL * (y[j] - y[i]) * (x[k] - x[i]);
long long rhs =
1LL * (y[k] - y[i]) * (x[j] - x[i]);
if (lhs == rhs)
cnt++;
}
// Update the maximum number of points on a line
ans = max(ans, cnt);
}
}
return ans;
}
int main()
{
vector<int> x = {-1, 0, 1, 2, 3, 3};
vector<int> y = {1, 0, 1, 2, 3, 4};
cout << maxPoints(x, y) << endl;
return 0;
}
import java.util.Arrays;
public class GFG {
public static int maxPoints(int[] x, int[] y) {
int n = x.length;
// If there are 2 or fewer points,
// return the number of points
if (n <= 2)
return n;
int ans = 1;
// Iterate through each pair of points
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// Skip identical points
if (x[i] == x[j] && y[i] == y[j])
continue;
int cnt = 0;
// Check other points to see if they lie on the same line
for (int k = 0; k < n; k++) {
long lhs =
1L * (y[j] - y[i]) * (x[k] - x[i]);
long rhs =
1L * (y[k] - y[i]) * (x[j] - x[i]);
if (lhs == rhs)
cnt++;
}
// Update the maximum number of points on a line
ans = Math.max(ans, cnt);
}
}
return ans;
}
public static void main(String[] args) {
int[] x = {-1, 0, 1, 2, 3, 3};
int[] y = {1, 0, 1, 2, 3, 4};
System.out.println(maxPoints(x, y));
}
}
def maxPoints(x, y):
n = len(x)
# If there are 2 or fewer points,
# return the number of points
if n <= 2:
return n
ans = 1
# Iterate through each pair of points
for i in range(n):
for j in range(i + 1, n):
# Skip identical points
if x[i] == x[j] and y[i] == y[j]:
continue
cnt = 0
# Check other points to see if they lie on the same line
for k in range(n):
lhs = (y[j] - y[i]) * (x[k] - x[i])
rhs = (y[k] - y[i]) * (x[j] - x[i])
if lhs == rhs:
cnt += 1
# Update the maximum number of points on a line
ans = max(ans, cnt)
return ans
if __name__ == "__main__":
x = [-1, 0, 1, 2, 3, 3]
y = [1, 0, 1, 2, 3, 4]
print(maxPoints(x, y))
using System;
public class GFG
{
public static int maxPoints(int[] x, int[] y)
{
int n = x.Length;
// If there are 2 or fewer points,
// return the number of points
if (n <= 2)
return n;
int ans = 1;
// Iterate through each pair of points
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
// Skip identical points
if (x[i] == x[j] && y[i] == y[j])
continue;
int cnt = 0;
// Check other points to see if they lie on the same line
for (int k = 0; k < n; k++)
{
long lhs =
(long)(y[j] - y[i]) * (x[k] - x[i]);
long rhs =
(long)(y[k] - y[i]) * (x[j] - x[i]);
if (lhs == rhs)
cnt++;
}
// Update the maximum number of points on a line
ans = Math.Max(ans, cnt);
}
}
return ans;
}
public static void Main()
{
int[] x = {-1, 0, 1, 2, 3, 3};
int[] y = {1, 0, 1, 2, 3, 4};
Console.WriteLine(maxPoints(x, y));
}
}
function maxPoints(x, y) {
const n = x.length;
// If there are 2 or fewer points,
// return the number of points
if (n <= 2)
return n;
let ans = 1;
// Iterate through each pair of points
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
// Skip identical points
if (x[i] === x[j] && y[i] === y[j])
continue;
let cnt = 0;
// Check other points to see if they lie on the same line
for (let k = 0; k < n; k++) {
const lhs =
(y[j] - y[i]) * (x[k] - x[i]);
const rhs =
(y[k] - y[i]) * (x[j] - x[i]);
if (lhs === rhs)
cnt++;
}
// Update the maximum number of points on a line
ans = Math.max(ans, cnt);
}
}
return ans;
}
// Driver code
const x = [-1, 0, 1, 2, 3, 3];
const y = [1, 0, 1, 2, 3, 4];
console.log(maxPoints(x, y));
[Expected Approach] Slope Hashing - O(n²) Time and O(n) Space
For each point, calculate slopes to all other points. Points with same slope lie on same line. Use normalized slope as key in hash map. Track maximum points including overlaps and vertical lines.
- If n < 2, return n
- For each point i, create empty slope map
- For each point j > i, compute slope (yDif / xDif)
- If points are identical, increment overlapPoints
- If x coordinates are same, increment verticalPoints
- Else reduce slope by gcd and normalize to ensure uniqueness
- Store slope as string key and increment count
- Track curMax as maximum of slope counts and verticalPoints
- Update global maxPoint with curMax + overlapPoints + 1
- Clear map for next point
- Return maxPoint
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int maxPoints(vector<int>& x, vector<int>& y)
{
int n = x.size();
if (n < 2)
return n;
int maxPoint = 0;
int curMax, overlapPoints, verticalPoints;
// Stores frequency of each slope
unordered_map<string, int> 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 (x[i] == x[j] && y[i] == y[j])
overlapPoints++;
// If x co-ordinate is same, then both
// point are vertical to each other
else if (x[i] == x[j])
verticalPoints++;
else
{
int yDif = y[j] - y[i];
int xDif = x[j] - x[i];
int g = __gcd(abs(xDif), abs(yDif));
// reducing the difference by their gcd
yDif /= g;
xDif /= g;
if (xDif < 0)
{
xDif *= -1;
yDif *= -1;
}
string slope = to_string(yDif) + "#" + to_string(xDif);
// increasing the frequency of current slope
// in map
slopeMap[slope]++;
curMax = max(curMax, slopeMap[slope]);
}
curMax = max(curMax, verticalPoints);
}
// updating global maximum by current point's maximum
maxPoint = max(maxPoint,
curMax + overlapPoints + 1);
slopeMap.clear();
}
return maxPoint;
}
int main()
{
vector<int> x = {-1, 0, 1, 2, 3, 3};
vector<int> y = {1, 0, 1, 2, 3, 4};
cout << maxPoints(x, y) << endl;
return 0;
}
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
class GFG {
// GCD function
static int gcd(int a, int b) {
a = Math.abs(a);
b = Math.abs(b);
return b == 0? a : gcd(b, a % b);
}
// method to find maximum collinear points
static int maxPoints(int[] x, int[] y) {
int N = x.length;
if (N < 2)
return N;
int maxPoint = 0;
// Stores frequency of each slope
Map<String, Integer> slopeMap = new HashMap<>();
// looping for each point
for (int i = 0; i < N; i++) {
int curMax = 0;
int overlapPoints = 0;
int verticalPoints = 0;
// looping from i + 1 to ignore same pair again
for (int j = i + 1; j < N; j++) {
// If both points are equal then just increase overlapPoint count
if (x[i] == x[j] && y[i] == y[j]) {
overlapPoints++;
}
// If x co-ordinate is same, then both points are vertical to each other
else if (x[i] == x[j]) {
verticalPoints++;
} else {
int yDif = y[j] - y[i];
int xDif = x[j] - x[i];
int g = gcd(xDif, yDif);
// reducing the difference by their gcd
yDif /= g;
xDif /= g;
if (xDif < 0) {
xDif *= -1;
yDif *= -1;
}
String slope = yDif + "#" + xDif;
// increasing the frequency of current slope in map
slopeMap.put(slope, slopeMap.getOrDefault(slope, 0) + 1);
curMax = Math.max(curMax, slopeMap.get(slope));
}
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[] x = {-1, 0, 1, 2, 3, 3};
int[] y = {1, 0, 1, 2, 3, 4};
System.out.println(maxPoints(x, y));
}
}
from math import gcd
def maxPoints(x, y):
n = len(x)
if n < 2:
return n
maxPoint = 0
# looping for each point
for i in range(n):
curMax = 0
overlapPoints = 0
verticalPoints = 0
# Stores frequency of each slope
slopeMap = {}
# looping from i + 1 to ignore same pair again
for j in range(i + 1, n):
# If both points are equal then just
# increase overlapPoint count
if x[i] == x[j] and y[i] == y[j]:
overlapPoints += 1
# If x co-ordinate is same, then both points
# are vertical to each other
elif x[i] == x[j]:
verticalPoints += 1
else:
yDif = y[j] - y[i]
xDif = x[j] - x[i]
g = gcd(abs(xDif), abs(yDif))
# reducing the difference by their gcd
yDif //= g
xDif //= g
if xDif < 0:
xDif *= -1
yDif *= -1
slope = f"{yDif}#{xDif}"
# increasing the frequency of current slope in map
slopeMap[slope] = slopeMap.get(slope, 0) + 1
curMax = max(curMax, slopeMap[slope])
curMax = max(curMax, verticalPoints)
# updating global maximum by current point's maximum
maxPoint = max(maxPoint, curMax + overlapPoints + 1)
return maxPoint
if __name__ == "__main__":
x = [-1, 0, 1, 2, 3, 3]
y = [1, 0, 1, 2, 3, 4]
print(maxPoints(x, y))
using System;
using System.Collections.Generic;
class GFG {
// GCD function
static int gcd(int a, int b) {
a = Math.Abs(a);
b = Math.Abs(b);
return b == 0? a : gcd(b, a % b);
}
// method to find maximum collinear points
static int maxPoints(int[] x, int[] y) {
int N = x.Length;
if (N < 2)
return N;
int maxPoint = 0;
// Stores frequency of each slope
Dictionary<string, int> slopeMap = new Dictionary<string, int>();
// looping for each point
for (int i = 0; i < N; i++) {
int curMax = 0;
int overlapPoints = 0;
int verticalPoints = 0;
// looping from i + 1 to ignore same pair again
for (int j = i + 1; j < N; j++) {
// If both points are equal then just
// increase overlapPoint count
if (x[i] == x[j] && y[i] == y[j]) {
overlapPoints++;
}
// If x co-ordinate is same, then both points
// are vertical to each other
else if (x[i] == x[j]) {
verticalPoints++;
} else {
int yDif = y[j] - y[i];
int xDif = x[j] - x[i];
int g = gcd(xDif, yDif);
// reducing the difference by their gcd
yDif /= g;
xDif /= g;
if (xDif < 0) {
xDif *= -1;
yDif *= -1;
}
string slope = yDif + "#" + xDif;
// increasing the frequency of current slope in map
if (slopeMap.ContainsKey(slope))
slopeMap[slope]++;
else
slopeMap[slope] = 1;
curMax = Math.Max(curMax, slopeMap[slope]);
}
curMax = Math.Max(curMax, verticalPoints);
}
// updating global maximum by current point's maximum
maxPoint = Math.Max(maxPoint, curMax + overlapPoints + 1);
slopeMap.Clear();
}
return maxPoint;
}
static void Main(string[] args) {
int[] x = new int[] { -1, 0, 1, 2, 3, 3 };
int[] y = new int[] { 1, 0, 1, 2, 3, 4 };
Console.WriteLine(maxPoints(x, y));
}
}
// GCD function
function gcd(a, b) {
a = Math.abs(a);
b = Math.abs(b);
return b === 0 ? a : gcd(b, a % b);
}
// method to find maximum collinear points
function maxPoints(x, y) {
const n = x.length;
if (n< 2)
return n;
let maxPoint = 0;
// Stores frequency of each slope
let slopeMap = new Map();
// looping for each point
for (let i = 0; i < n; i++) {
let curMax = 0;
let overlapPoints = 0;
let verticalPoints = 0;
// looping from i + 1 to ignore same pair again
for (let j = i + 1; j < n; j++) {
// If both points are equal then just increase overlapPoint count
if (x[i] === x[j] && y[i] === y[j]) {
overlapPoints++;
}
// If x co-ordinate is same, then both points are vertical to each other
else if (x[i] === x[j]) {
verticalPoints++;
} else {
let yDif = y[j] - y[i];
let xDif = x[j] - x[i];
let g = gcd(xDif, yDif);
// reducing the difference by their gcd
yDif /= g;
xDif /= g;
if (xDif < 0) {
xDif *= -1;
yDif *= -1;
}
let slope = yDif + "#" + xDif;
// increasing the frequency of current slope in map
slopeMap.set(slope, (slopeMap.get(slope) || 0) + 1);
curMax = Math.max(curMax, slopeMap.get(slope));
}
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
const x = [-1, 0, 1, 2, 3, 3];
const y = [1, 0, 1, 2, 3, 4];
console.log(maxPoints(x, y));
Output
4

