Count maximum points on same line

Last Updated : 10 Jul, 2026

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)

Try It Yourself
redirect icon

[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
C++
#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;
}
Java
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));
    }
}
Python
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))
C#
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));
    }
}
JavaScript
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
C++
#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;
}
Java
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));
    }
}
Python
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))
C#
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));
    }
}
JavaScript
// 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
Comment