---
# System prepended metadata

title: 0963. Minimum Area Rectangle II
tags: [Leetcode, FaceBook, Medium]

---

# 0963. Minimum Area Rectangle II
###### tags: `Leetcode` `Medium` `FaceBook`
Link: https://leetcode.com/problems/minimum-area-rectangle-ii/
## 思路
由于如果两条边长度相等且中点重合，那么两条边的四个顶点就可以构成一个矩形
所以用```Map<Double, Map<Point,List<Point>>>```,第一个key是边的长度，第二个key是center
用边长而不是center做第一个key是因为第31行，需要用center算另外一个点，然后求面积
对于两个点，先算出边长，然后算center，然后存进map里面，但只要存一个点就好了
后面对于每个边长每个center，把它存的点都拿出来，对于每两个点P和Q，先通过Q和center算出对于center对称的点Q2，已知三个点求矩形面积

在写这个题目的时候出现了一个bug，一开始我是自己建了一个class叫做point里面存x和y，但是由于没有**重写compare 或者 equals function**，存进map时候比对的是对象地址，所以对于每一个center，里面只有一个点，就会出bug
解决办法是用pair或者java.awt.Point

建议用java.awt.Point, 需要掌握的函数有
- get x和y值 直接a.x a.y
- new 对象 new Point(x,y)
## Code
用point
```java=
import java.awt.Point;
class Solution {
    public double computeLen(Point a, Point b){
        return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    }
    public double minAreaFreeRect(int[][] points) {
        Map<Double,Map<Point,List<Point>>> lenToPoints = new HashMap<>();
        Point[] pointSet = new Point[points.length];
        for(int i = 0;i < points.length;i++){
           pointSet[i] = new Point(points[i][0],points[i][1]); 
        }
        
        for(int i = 0;i < points.length-1;i++){
            for(int j = i+1;j < points.length;j++){
                //get center
                Point center = new Point(pointSet[i].x+pointSet[j].x, pointSet[i].y+pointSet[j].y);
                //get length
                double len = computeLen(pointSet[i],pointSet[j]);
                if(!lenToPoints.containsKey(len)){
                    lenToPoints.put(len, new HashMap<Point,List<Point>>());
                }
                
                Map<Point, List<Point>> centerToPoints = lenToPoints.get(len);
                
                if(!centerToPoints.containsKey(center)) centerToPoints.put(center, new ArrayList<>());
                centerToPoints.get(center).add(pointSet[i]);
            }
        }
        
        double minArea = Double.MAX_VALUE;
        for(Map<Point,List<Point>> info:lenToPoints.values()){
            for(Point center:info.keySet()){
                List<Point> candidates = info.get(center);
                for(int i = 0;i < candidates.size()-1;i++){
                    for(int j = i+1;j < candidates.size();j++){
                        Point P = candidates.get(i);
                        Point Q = candidates.get(j);
                        Point Q2 = new Point(center.x-Q.x, center.y-Q.y);
                        double area = Math.sqrt(computeLen(P,Q))*Math.sqrt(computeLen(P,Q2));
                        minArea = Math.min(minArea, area);                                         
                    }
                }
            }
        }
        return minArea==Double.MAX_VALUE?0:minArea;
    }
}
```
用pair 好复杂...
```java=
class Solution {
    public double minAreaFreeRect(int[][] points) {
        Map<Integer, Map<Pair<Integer, Integer>, List<Pair<Integer, Integer>>>> map = new HashMap<>();
        for(int i = 0;i < points.length-1;i++){
            for(int j = i+1;j < points.length;j++){
                Pair<Integer,Integer> a = new Pair<>(points[i][0], points[i][1]);
                Pair<Integer,Integer> b = new Pair<>(points[j][0], points[j][1]);
                int len = computeLen(a,b);
                Pair<Integer, Integer> center = getCenter(a,b);
                if(!map.containsKey(len)) map.put(len, new HashMap<>());
                Map<Pair<Integer, Integer>, List<Pair<Integer,Integer>>> subMap = map.get(len);
                if(!subMap.containsKey(center)) subMap.put(center, new ArrayList<>());
                subMap.get(center).add(a);
            }
        }
        
        double minArea = Double.MAX_VALUE;
        for(Map<Pair<Integer, Integer>, List<Pair<Integer, Integer>>> info:map.values()){
            for(Pair<Integer, Integer> center:info.keySet()){
                List<Pair<Integer, Integer>> candidates = info.get(center);
                for(int i = 0;i < candidates.size()-1;i++){
                    for(int j = i+1;j < candidates.size();j++){
                        Pair<Integer,Integer> a = candidates.get(i);
                        Pair<Integer,Integer> b = candidates.get(j);
                        Pair<Integer,Integer> c = getAnotherPoint(center, a);
                        double area = Math.sqrt(computeLen(a,b))*Math.sqrt(computeLen(b,c));
                        if(area < minArea){
                            minArea = area;
                        }
                        
                    }
                }
            } 
        }
        return minArea == Double.MAX_VALUE?0:minArea;
    }
    private int computeLen(Pair<Integer,Integer> a, Pair<Integer,Integer> b){
        return (a.getKey()-b.getKey())*(a.getKey()-b.getKey())+(a.getValue()-b.getValue())*(a.getValue()-b.getValue());
    }
    private Pair<Integer, Integer> getCenter(Pair<Integer,Integer> a, Pair<Integer,Integer> b){
        return new Pair<>(a.getKey()+b.getKey(),a.getValue()+b.getValue());
    }
    private Pair<Integer, Integer> getAnotherPoint(Pair<Integer,Integer> center, Pair<Integer, Integer> a){
        return new Pair<>(center.getKey()-a.getKey(),center.getValue()-a.getValue());
    }
}
```