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.
Move from brute-force thinking to an efficient approach using array strategy.
You are given an array of points in the X-Y plane points where points[i] = [xi, yi].
Return the minimum area of a rectangle formed from these points, with sides parallel to the X and Y axes. If there is not any such rectangle, return 0.
Example 1:
Input: points = [[1,1],[1,3],[3,1],[3,3],[2,2]] Output: 4
Example 2:
Input: points = [[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]] Output: 2
Constraints:
1 <= points.length <= 500points[i].length == 20 <= xi, yi <= 4 * 104Problem summary: You are given an array of points in the X-Y plane points where points[i] = [xi, yi]. Return the minimum area of a rectangle formed from these points, with sides parallel to the X and Y axes. If there is not any such rectangle, return 0.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Math
[[1,1],[1,3],[3,1],[3,3],[2,2]]
[[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]]
minimum-rectangles-to-cover-points)maximum-area-rectangle-with-point-constraints-i)maximum-area-rectangle-with-point-constraints-ii)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #939: Minimum Area Rectangle
class Solution {
public int minAreaRect(int[][] points) {
TreeMap<Integer, List<Integer>> d = new TreeMap<>();
for (var p : points) {
int x = p[0], y = p[1];
d.computeIfAbsent(x, k -> new ArrayList<>()).add(y);
}
Map<Integer, Integer> pos = new HashMap<>();
int ans = 1 << 30;
for (var e : d.entrySet()) {
int x = e.getKey();
var ys = e.getValue();
Collections.sort(ys);
int n = ys.size();
for (int i = 0; i < n; ++i) {
int y1 = ys.get(i);
for (int j = i + 1; j < n; ++j) {
int y2 = ys.get(j);
int p = y1 * 40001 + y2;
if (pos.containsKey(p)) {
ans = Math.min(ans, (x - pos.get(p)) * (y2 - y1));
}
pos.put(p, x);
}
}
}
return ans == 1 << 30 ? 0 : ans;
}
}
// Accepted solution for LeetCode #939: Minimum Area Rectangle
func minAreaRect(points [][]int) int {
d := map[int][]int{}
xs := []int{}
for _, p := range points {
x, y := p[0], p[1]
d[x] = append(d[x], y)
}
for x := range d {
xs = append(xs, x)
}
sort.Ints(xs)
type pair struct{ x, y int }
pos := map[pair]int{}
ans := 1 << 30
for _, x := range xs {
ys := d[x]
sort.Ints(ys)
for i, y1 := range ys {
for _, y2 := range ys[i+1:] {
p := pair{y1, y2}
if x1, ok := pos[p]; ok {
ans = min(ans, (x-x1)*(y2-y1))
}
pos[p] = x
}
}
}
if ans == 1<<30 {
return 0
}
return ans
}
# Accepted solution for LeetCode #939: Minimum Area Rectangle
class Solution:
def minAreaRect(self, points: List[List[int]]) -> int:
d = defaultdict(list)
for x, y in points:
d[x].append(y)
pos = {}
ans = inf
for x in sorted(d):
ys = d[x]
ys.sort()
n = len(ys)
for i, y1 in enumerate(ys):
for y2 in ys[i + 1 :]:
if (y1, y2) in pos:
ans = min(ans, (x - pos[(y1, y2)]) * (y2 - y1))
pos[(y1, y2)] = x
return 0 if ans == inf else ans
// Accepted solution for LeetCode #939: Minimum Area Rectangle
struct Solution;
use std::collections::HashSet;
use std::i32;
impl Solution {
fn min_area_rect(points: Vec<Vec<i32>>) -> i32 {
let n = points.len();
let mut hs: HashSet<(i32, i32)> = HashSet::new();
for i in 0..n {
hs.insert((points[i][0], points[i][1]));
}
let mut min = i32::MAX;
for i in 0..n - 1 {
for j in i + 1..n {
let x1 = points[i][0];
let y1 = points[i][1];
let x2 = points[j][0];
let y2 = points[j][1];
if x2 != x1 && y2 != y1 && hs.contains(&(x1, y2)) && hs.contains(&(x2, y1)) {
min = min.min((x2 - x1).abs() * (y2 - y1).abs())
}
}
}
if min == i32::MAX {
0
} else {
min
}
}
}
#[test]
fn test() {
let points = vec_vec_i32![[1, 1], [1, 3], [3, 1], [3, 3], [2, 2]];
let res = 4;
assert_eq!(Solution::min_area_rect(points), res);
let points = vec_vec_i32![[1, 1], [1, 3], [3, 1], [3, 3], [4, 1], [4, 3]];
let res = 2;
assert_eq!(Solution::min_area_rect(points), res);
}
// Accepted solution for LeetCode #939: Minimum Area Rectangle
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #939: Minimum Area Rectangle
// class Solution {
// public int minAreaRect(int[][] points) {
// TreeMap<Integer, List<Integer>> d = new TreeMap<>();
// for (var p : points) {
// int x = p[0], y = p[1];
// d.computeIfAbsent(x, k -> new ArrayList<>()).add(y);
// }
// Map<Integer, Integer> pos = new HashMap<>();
// int ans = 1 << 30;
// for (var e : d.entrySet()) {
// int x = e.getKey();
// var ys = e.getValue();
// Collections.sort(ys);
// int n = ys.size();
// for (int i = 0; i < n; ++i) {
// int y1 = ys.get(i);
// for (int j = i + 1; j < n; ++j) {
// int y2 = ys.get(j);
// int p = y1 * 40001 + y2;
// if (pos.containsKey(p)) {
// ans = Math.min(ans, (x - pos.get(p)) * (y2 - y1));
// }
// pos.put(p, x);
// }
// }
// }
// return ans == 1 << 30 ? 0 : ans;
// }
// }
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.