AlgoMaster Logo

Minimum Area Rectangle

mediumFrequencyUpdated September 21, 2026

Understanding the Problem

We have a set of points scattered on a 2D plane, and we need to find the smallest rectangle whose sides are parallel to the axes. The phrase "sides parallel to the axes" is the constraint that shapes every approach. It means the rectangle's edges are horizontal and vertical, never tilted. A rectangle is therefore fully determined by choosing two distinct x-coordinates and two distinct y-coordinates, which gives four corners.

The question is then: among all axis-aligned rectangles whose four corners all exist in the point set, which one has the smallest area? If no such rectangle exists, we return 0.

One property drives most of the efficient solutions. An axis-aligned rectangle is defined by exactly two diagonal corners. Given two points that share neither x nor y, the other two corners are forced to be (x1, y2) and (x2, y1). That turns "find four points that form a rectangle" into "find two points and check whether two specific points exist."

Key Constraints:

  • 1 <= points.length <= 500 → With n up to 500, an O(n^2) solution does about 250,000 pair checks, which runs instantly. The O(n^4) brute force does roughly 2.6 billion quadruple checks, which is too slow.
  • 0 <= xi, yi <= 4 * 10^4 → Coordinates are non-negative integers up to 40,000, so we can use them directly as hash keys with no floating-point issues. The largest possible area is 40000 40000 = 1.6 10^9, which fits in a signed 32-bit integer (max about 2.1 * 10^9), so plain int is safe.
  • All points are unique → No duplicate handling needed.

Approach 1: Brute Force (Check All Quadruples)

Intuition

Try every combination of four points and check whether they form an axis-aligned rectangle. Four points qualify when they contain exactly two distinct x-coordinates and exactly two distinct y-coordinates, and every one of the four (x, y) combinations is present.

This is direct to implement but slow. With n up to 500, the number of 4-point combinations is C(500, 4), roughly 2.6 billion, which is far too many.

Algorithm

  1. For every combination of four points from the input, extract their x and y coordinates.
  2. Check if the four points have exactly two distinct x-values and two distinct y-values.
  3. Verify that all four corner combinations (x1,y1), (x1,y2), (x2,y1), (x2,y2) are present.
  4. If valid, compute the area as |x2 - x1| * |y2 - y1| and track the minimum.
  5. Return the minimum area found, or 0 if no rectangle exists.

Example Walkthrough

1Try all C(5,4)=5 quadruples of points
0
1
0
1
1
1
1
3
2
3
1
3
3
3
4
2
1
1/5

Code

Most quadruples don't form rectangles, so most of that work is wasted. The next approach picks two diagonal corners and verifies whether the other two exist in a hash set, cutting the search from quadruples to pairs.

Approach 2: Diagonal Pair with Hash Set

Intuition

An axis-aligned rectangle is fully defined by two diagonal corners. Pick two points (x1, y1) and (x2, y2) with x1 != x2 and y1 != y2, and the remaining corners are forced to be (x1, y2) and (x2, y1). So instead of searching for four points that happen to form a rectangle, we iterate over pairs and verify the two forced corners.

We store all points in a hash set for O(1) lookups. For each pair with different x and y coordinates, we check whether (x1, y2) and (x2, y1) both exist. If they do, the four points form a rectangle and we compute its area. This drops the cost from O(n^4) quadruples to O(n^2) pairs, each with O(1) lookups.

Algorithm

  1. Store all points in a hash set for O(1) existence checks.
  2. For every pair of points (x1, y1) and (x2, y2):
    • Skip if x1 == x2 or y1 == y2 (they can't be diagonal corners).
    • Check if (x1, y2) and (x2, y1) both exist in the set.
    • If so, compute the area |x2 - x1| * |y2 - y1| and update the minimum.
  3. Return the minimum area, or 0 if no rectangle was found.

Example Walkthrough

1Initialize: pointSet = {(1,1),(1,3),(3,1),(3,3),(2,1)}, minArea = inf
0
1
0
1
1
1
1
3
2
3
1
3
3
3
4
2
1
1/6

Code

This checks every pair as a potential diagonal, but pairs that share an x-coordinate can never be diagonal corners and are wasted work. The next approach groups points by column and looks only at y-pairs shared between columns, which performs much better when points cluster into few columns.

Approach 3: Column-Based with Sorted Y-Pairs

Intuition

Instead of checking all pairs of points, think column by column. Group all points by their x-coordinate. Each group is a list of y-values that share the same x. A rectangle needs two columns (two x-values) that share at least two y-values. So we iterate over pairs of y-values within each column, and for each y-pair we check whether the same y-pair appeared in an earlier column.

Process columns left to right by x-value. For each pair (y1, y2) in the current column, look it up in a map that records, for every y-pair, the x of the column where it last appeared. If the pair is present, the stored x and the current x form a rectangle of height (y2 - y1) and width (currentX - lastX). We then overwrite the stored x with the current one.

Storing only the most recent x is enough to find the minimum area. For a fixed y-pair (fixed height), area grows with width, so the smallest-area rectangle of that height comes from the smallest gap between two columns that contain the pair. Because columns are visited in increasing x order, comparing each column only against the immediately preceding one that held the pair covers the smallest gap for every height: any wider gap would yield a larger or equal area for the same height.

Algorithm

  1. Group all points by their x-coordinate into a map of x -> sorted list of y-values.
  2. Create a hash map lastX that maps each y-pair (y1, y2) to the most recent x-coordinate where that pair appeared.
  3. Sort the x-coordinates and iterate through each column.
  4. For each pair of y-values (y1, y2) in the current column:
    • If lastX already contains this y-pair, compute the area: (currentX - lastX[y1,y2]) * (y2 - y1). Update minimum.
    • Update lastX[y1,y2] to the current x-coordinate.
  5. Return the minimum area, or 0.

Example Walkthrough

1Columns: x=1→[1,3], x=3→[1,3], x=4→[1,3]. lastX = {}
1/6

Code