# 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()); } } ```