Minimum Area Rectangle
MediumUpdated: Aug 2, 2025
Practice on:
Problem
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.
Examples
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 * 10^4- All the given points are unique.
Solution
Method 1 – Hash Set + Pair Enumeration
Intuition
To find the minimum area rectangle, we need to find two pairs of points that share the same x or y coordinates and form the opposite corners of a rectangle. By storing all points in a set, we can efficiently check if the other two corners exist for each pair of points.
Approach
- Store all points in a set for O(1) lookup.
- For each pair of points, if they are not on the same line (x1 ≠ x2 and y1 ≠ y2), check if the other two corners (x1, y2) and (x2, y1) exist in the set.
- If so, compute the area and update the minimum area found.
- Return the minimum area, or 0 if no rectangle is found.
Code
C++
class Solution {
public:
int minAreaRect(vector<vector<int>>& points) {
set<pair<int,int>> st;
for (auto& p : points) st.insert({p[0], p[1]});
int ans = INT_MAX;
for (int i = 0; i < points.size(); ++i) {
for (int j = i+1; j < points.size(); ++j) {
int x1 = points[i][0], y1 = points[i][1];
int x2 = points[j][0], y2 = points[j][1];
if (x1 != x2 && y1 != y2) {
if (st.count({x1, y2}) && st.count({x2, y1})) {
ans = min(ans, abs(x1-x2)*abs(y1-y2));
}
}
}
}
return ans == INT_MAX ? 0 : ans;
}
};
Go
func minAreaRect(points [][]int) int {
st := map[[2]int]struct{}{}
for _, p := range points {
st[[2]int{p[0], p[1]}] = struct{}{}
}
ans := 1 << 30
for i := 0; i < len(points); i++ {
for j := i+1; j < len(points); j++ {
x1, y1 := points[i][0], points[i][1]
x2, y2 := points[j][0], points[j][1]
if x1 != x2 && y1 != y2 {
if _, ok1 := st[[2]int{x1, y2}]; ok1 {
if _, ok2 := st[[2]int{x2, y1}]; ok2 {
area := abs(x1-x2) * abs(y1-y2)
if area < ans { ans = area }
}
}
}
}
}
if ans == 1<<30 { return 0 }
return ans
}
func abs(x int) int { if x < 0 { return -x }; return x }
Java
class Solution {
public int minAreaRect(int[][] points) {
Set<String> st = new HashSet<>();
for (int[] p : points) st.add(p[0] + "," + p[1]);
int ans = Integer.MAX_VALUE;
for (int i = 0; i < points.length; ++i) {
for (int j = i+1; j < points.length; ++j) {
int x1 = points[i][0], y1 = points[i][1];
int x2 = points[j][0], y2 = points[j][1];
if (x1 != x2 && y1 != y2) {
if (st.contains(x1+","+y2) && st.contains(x2+","+y1)) {
ans = Math.min(ans, Math.abs(x1-x2)*Math.abs(y1-y2));
}
}
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}
Kotlin
class Solution {
fun minAreaRect(points: Array<IntArray>): Int {
val st = mutableSetOf<Pair<Int,Int>>()
for (p in points) st.add(p[0] to p[1])
var ans = Int.MAX_VALUE
for (i in points.indices) {
for (j in i+1 until points.size) {
val (x1, y1) = points[i]
val (x2, y2) = points[j]
if (x1 != x2 && y1 != y2) {
if ((x1 to y2) in st && (x2 to y1) in st) {
ans = minOf(ans, kotlin.math.abs(x1-x2)*kotlin.math.abs(y1-y2))
}
}
}
}
return if (ans == Int.MAX_VALUE) 0 else ans
}
}
Python
def min_area_rect(points: list[list[int]]) -> int:
st = set((x, y) for x, y in points)
ans = float('inf')
for i in range(len(points)):
for j in range(i+1, len(points)):
x1, y1 = points[i]
x2, y2 = points[j]
if x1 != x2 and y1 != y2:
if (x1, y2) in st and (x2, y1) in st:
area = abs(x1-x2) * abs(y1-y2)
ans = min(ans, area)
return 0 if ans == float('inf') else ans
Rust
impl Solution {
pub fn min_area_rect(points: Vec<Vec<i32>>) -> i32 {
use std::collections::HashSet;
let st: HashSet<(i32,i32)> = points.iter().map(|p| (p[0], p[1])).collect();
let mut ans = i32::MAX;
for i in 0..points.len() {
for j in i+1..points.len() {
let (x1, y1) = (points[i][0], points[i][1]);
let (x2, y2) = (points[j][0], points[j][1]);
if x1 != x2 && y1 != y2 {
if st.contains(&(x1, y2)) && st.contains(&(x2, y1)) {
let area = (x1-x2).abs() * (y1-y2).abs();
ans = ans.min(area);
}
}
}
}
if ans == i32::MAX { 0 } else { ans }
}
}
TypeScript
class Solution {
minAreaRect(points: number[][]): number {
const st = new Set(points.map(([x, y]) => `${x},${y}`));
let ans = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < points.length; ++i) {
for (let j = i+1; j < points.length; ++j) {
const [x1, y1] = points[i];
const [x2, y2] = points[j];
if (x1 !== x2 && y1 !== y2) {
if (st.has(`${x1},${y2}`) && st.has(`${x2},${y1}`)) {
const area = Math.abs(x1-x2) * Math.abs(y1-y2);
ans = Math.min(ans, area);
}
}
}
}
return ans === Number.MAX_SAFE_INTEGER ? 0 : ans;
}
}
Complexity
- ⏰ Time complexity:
O(n^2)- Checking all pairs of points.
- 🧺 Space complexity:
O(n)- For storing points in a set.