Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
Given an array of points where points[i] = [xi, yi] represents a point on the X-Y plane, return the maximum number of points that lie on the same straight line.
Example 1:
Input: points = [[1,1],[2,2],[3,3]] Output: 3
Example 2:
Input: points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]] Output: 4
Constraints:
1 <= points.length <= 300points[i].length == 2-104 <= xi, yi <= 104points are unique.Problem summary: Given an array of points where points[i] = [xi, yi] represents a point on the X-Y plane, return the maximum number of points that lie on the same straight line.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Math
[[1,1],[2,2],[3,3]]
[[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
line-reflection)minimum-number-of-lines-to-cover-points)minimum-lines-to-represent-a-line-chart)count-special-subsequences)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #149: Max Points on a Line
class Solution {
public int maxPoints(int[][] points) {
int n = points.length;
int ans = 1;
for (int i = 0; i < n; ++i) {
int x1 = points[i][0], y1 = points[i][1];
for (int j = i + 1; j < n; ++j) {
int x2 = points[j][0], y2 = points[j][1];
int cnt = 2;
for (int k = j + 1; k < n; ++k) {
int x3 = points[k][0], y3 = points[k][1];
int a = (y2 - y1) * (x3 - x1);
int b = (y3 - y1) * (x2 - x1);
if (a == b) {
++cnt;
}
}
ans = Math.max(ans, cnt);
}
}
return ans;
}
}
// Accepted solution for LeetCode #149: Max Points on a Line
func maxPoints(points [][]int) int {
n := len(points)
ans := 1
for i := 0; i < n; i++ {
x1, y1 := points[i][0], points[i][1]
for j := i + 1; j < n; j++ {
x2, y2 := points[j][0], points[j][1]
cnt := 2
for k := j + 1; k < n; k++ {
x3, y3 := points[k][0], points[k][1]
a := (y2 - y1) * (x3 - x1)
b := (y3 - y1) * (x2 - x1)
if a == b {
cnt++
}
}
if ans < cnt {
ans = cnt
}
}
}
return ans
}
# Accepted solution for LeetCode #149: Max Points on a Line
class Solution:
def maxPoints(self, points: List[List[int]]) -> int:
n = len(points)
ans = 1
for i in range(n):
x1, y1 = points[i]
for j in range(i + 1, n):
x2, y2 = points[j]
cnt = 2
for k in range(j + 1, n):
x3, y3 = points[k]
a = (y2 - y1) * (x3 - x1)
b = (y3 - y1) * (x2 - x1)
cnt += a == b
ans = max(ans, cnt)
return ans
// Accepted solution for LeetCode #149: Max Points on a Line
use std::collections::HashMap;
impl Solution {
pub fn max_points(points: Vec<Vec<i32>>) -> i32 {
let mut res = 1;
for i in 0..points.len() {
let point1 = &points[i];
let mut count = HashMap::new();
for j in (i + 1)..points.len() {
let point2 = &points[j];
let slope;
if point2[0] == point1[0] {
slope = i32::MAX;
} else {
slope = ((point2[1] as f64 - point1[1] as f64)
/ (point2[0] as f64 - point1[0] as f64)
* 100000.0) as i32;
}
*count.entry(slope).or_insert(1) += 1;
res = res.max(*count.get(&slope).unwrap());
}
}
res
}
}
// Accepted solution for LeetCode #149: Max Points on a Line
function maxPoints(points: number[][]): number {
let res = 1;
for (let i = 0; i < points.length; i++) {
const count = new Map();
const point1 = points[i];
for (let j = i + 1; j < points.length; j++) {
const point2 = points[j];
let slope;
if (point2[0] === point1[0]) {
slope = Number.MAX_SAFE_INTEGER;
} else {
slope = (point2[1] - point1[1]) / (point2[0] - point1[0]);
}
!count.has(slope)
? count.set(slope, 2)
: count.set(slope, count.get(slope) + 1);
res = Math.max(res, count.get(slope));
}
}
return res;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.