Minimum Area Rectangle II

MediumGeometry · Hashing🧩 Math & GeometryLeetCode #963 ↗Updated

Problem

You are given distinct points points[i] = [x, y] in the plane. Find the smallest area of a rectangle whose four corners are all in the set. The rectangle may be rotated — its sides need not be parallel to the axes. Return 0 if no rectangle exists.
Input[[1,2],[2,1],[1,0],[0,1]]Output2.00000 (a tilted square)
Input[[0,1],[2,1],[1,1],[1,0],[2,0]]Output1.00000
Input[[0,3],[1,2],[3,1],[1,3],[2,1]]Output0

1 ≤ points.length ≤ 50  ·  0 ≤ x, y ≤ 4·104  ·  all points distinct  ·  answers within 10-5 are accepted

Try it yourself

Java
class Solution {
    public double minAreaFreeRect(int[][] points) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
A quadrilateral is a rectangle exactly when its two diagonals share the same midpoint and the same length. So group all point pairs by (midpoint, length2); any two pairs in one group form a rectangle.
PatternMath & Geometry

Instinct Digits, factors, slopes or distances hide a formula - find the invariant, then guard against overflow, negatives and floating-point error.

Memory hack Mod peels, gcd reduces, squares compare - and long saves the day. Peel digits with %10, reduce slopes with gcd, compare squared distances.

Open the Math & Geometry guide →

Approaches

Brute ForceCheck Every 4-Point Combination

Time O(n4)Space O(1)

For each set of four points try the three ways to split them into two diagonals. If a split has equal midpoints and equal diagonal lengths it is a rectangle; its sides run from one corner to the two other-diagonal points, so area = |side1| · |side2|.

Java
public double minAreaFreeRect(int[][] points) {
    int n = points.length;
    double best = Double.MAX_VALUE;
    for (int a = 0; a < n; a++)
        for (int b = a + 1; b < n; b++)
            for (int c = b + 1; c < n; c++)
                for (int d = c + 1; d < n; d++) {
                    int[][] q = {points[a], points[b], points[c], points[d]};
                    // three ways to pair the 4 points as diagonals
                    int[][] splits = {{0, 1, 2, 3}, {0, 2, 1, 3}, {0, 3, 1, 2}};
                    for (int[] s : splits) {
                        double area = area(q[s[0]], q[s[1]], q[s[2]], q[s[3]]);
                        if (area > 0) best = Math.min(best, area);
                    }
                }
    return best == Double.MAX_VALUE ? 0 : best;
}

// area if (p,q) and (r,s) are the diagonals of a rectangle, else 0
private double area(int[] p, int[] q, int[] r, int[] s) {
    boolean sameMid = p[0] + q[0] == r[0] + s[0] && p[1] + q[1] == r[1] + s[1];
    if (!sameMid || dist2(p, q) != dist2(r, s)) return 0;
    return Math.sqrt(dist2(p, r)) * Math.sqrt(dist2(p, s));
}

private long dist2(int[] u, int[] v) {
    long dx = u[0] - v[0], dy = u[1] - v[1];
    return dx * dx + dy * dy;
}

Simple and exact; ~230k combinations for n = 50 is fine but scales badly.

At a glance

LevelApproachTimeSpace
Brute ForceCheck Every 4-Point CombinationO(n4)O(1)
BetterFix a Right-Angle Corner + Hash SetO(n3)O(n)
OptimalGroup Diagonals by (Midpoint, Length)O(n3) worst, ~O(n2) typicalO(n2)
Common pitfalls
  • Using floating-point midpoints as map keys — use coordinate sums instead.
  • Equal midpoints alone give a parallelogram; the diagonals must also have equal length.
  • Squared distances up to 3.2·109 overflow int — use long.
Interview tips
  • State the rectangle test (equal, bisecting diagonals) before touching code.
  • Mention the O(n3) right-angle method as a solid fallback if hashing feels risky.
  • Explain how the area comes from two adjacent sides meeting at one corner.
Pattern
Geometry + hashing invariants → shape detection from a point set; hash an invariant (midpoint, length, slope) of point pairs.
My notes saved in this browser