Minimum Area Rectangle II

medium geometry hash set vectors

Problem

Given an array of points in the X-Y plane, find the minimum area of any rectangle formed using these points as vertices. The rectangle's sides need not be parallel to the axes — it may be rotated at any angle. Return 0 if no rectangle can be formed.

Inputpoints = [[1,2], [2,1], [1,0], [0,1]]
Output2.0
The four points form a square rotated 45°. Its side length is √2, so the area is √2 · √2 = 2.

def min_area_free_rect(points):
    pts = {(x, y) for x, y in points}
    best = float("inf")
    n = len(points)
    for i in range(n):
        x1, y1 = points[i]
        for j in range(n):
            if j == i:
                continue
            x2, y2 = points[j]
            for k in range(j + 1, n):
                if k == i:
                    continue
                x3, y3 = points[k]
                # P2 and P3 share corner P1; P4 = P2 + P3 - P1
                if (x2 - x1) * (x3 - x1) + (y2 - y1) * (y3 - y1) != 0:
                    continue
                x4, y4 = x2 + x3 - x1, y2 + y3 - y1
                if (x4, y4) in pts:
                    d12 = ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
                    d13 = ((x3 - x1) ** 2 + (y3 - y1) ** 2) ** 0.5
                    best = min(best, d12 * d13)
    return 0.0 if best == float("inf") else best
function minAreaFreeRect(points) {
  const pts = new Set(points.map(p => p[0] + "," + p[1]));
  let best = Infinity;
  const n = points.length;
  for (let i = 0; i < n; i++) {
    const [x1, y1] = points[i];
    for (let j = 0; j < n; j++) {
      if (j === i) continue;
      const [x2, y2] = points[j];
      for (let k = j + 1; k < n; k++) {
        if (k === i) continue;
        const [x3, y3] = points[k];
        if ((x2 - x1) * (x3 - x1) + (y2 - y1) * (y3 - y1) !== 0) continue;
        const x4 = x2 + x3 - x1, y4 = y2 + y3 - y1;
        if (pts.has(x4 + "," + y4)) {
          const d12 = Math.hypot(x2 - x1, y2 - y1);
          const d13 = Math.hypot(x3 - x1, y3 - y1);
          best = Math.min(best, d12 * d13);
        }
      }
    }
  }
  return best === Infinity ? 0 : best;
}
class Solution {
    public double minAreaFreeRect(int[][] points) {
        Set<Long> pts = new HashSet<>();
        for (int[] p : points) pts.add(40001L * p[0] + p[1]);
        double best = Double.MAX_VALUE;
        int n = points.length;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (j == i) continue;
                for (int k = j + 1; k < n; k++) {
                    if (k == i) continue;
                    int x1 = points[i][0], y1 = points[i][1];
                    int x2 = points[j][0], y2 = points[j][1];
                    int x3 = points[k][0], y3 = points[k][1];
                    if ((x2 - x1) * (x3 - x1) + (y2 - y1) * (y3 - y1) != 0) continue;
                    long key = 40001L * (x2 + x3 - x1) + (y2 + y3 - y1);
                    if (pts.contains(key)) {
                        double d12 = Math.hypot(x2 - x1, y2 - y1);
                        double d13 = Math.hypot(x3 - x1, y3 - y1);
                        best = Math.min(best, d12 * d13);
                    }
                }
            }
        }
        return best == Double.MAX_VALUE ? 0 : best;
    }
}
double minAreaFreeRect(vector<vector<int>>& points) {
    set<pair<int, int>> pts;
    for (auto& p : points) pts.insert({p[0], p[1]});
    double best = 1e18;
    int n = points.size();
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (j == i) continue;
            for (int k = j + 1; k < n; k++) {
                if (k == i) continue;
                int x1 = points[i][0], y1 = points[i][1];
                int x2 = points[j][0], y2 = points[j][1];
                int x3 = points[k][0], y3 = points[k][1];
                if ((x2 - x1) * (x3 - x1) + (y2 - y1) * (y3 - y1) != 0) continue;
                if (pts.count({x2 + x3 - x1, y2 + y3 - y1})) {
                    double d12 = hypot(x2 - x1, y2 - y1);
                    double d13 = hypot(x3 - x1, y3 - y1);
                    best = min(best, d12 * d13);
                }
            }
        }
    }
    return best == 1e18 ? 0 : best;
}
Time: O(n³) Space: O(n)