Perfect Rectangle

https://leetcode.com/problems/perfect-rectangle/#/solutions

这道题看着挺tricky,方块需要完美的拼出长方形。可以看出当有很多很多小方块时,每个方块大小不一样时,直接判断是否时完美长方形是很难的。一种思维是将条件转化为其他条件,比如面积来判断。开始想的是判断面积相等, 同时判断所有的点都在内部。

  • 错误尝试

  • 面积相等

  • 所有的点都在顶点内部(maxx1,maxy1,maxx2, maxy2)组成的顶点一定在长方形上

  • 忽略点:可能存在overlap,导致长方形面积一样,顶点符合要求。[[0,0,1,1],[0,1,3,2],[1,0,2,2]]

public class Solution {

    public boolean isRectangleCover(int[][] rectangles) {
        int area=0;
        int x1 = Integer.MAX_VALUE; int x2 = Integer.MIN_VALUE;
        int y1 = Integer.MAX_VALUE; int y2 = Integer.MIN_VALUE;
        for(int[] r : rectangles){
            x1 = Math.min(x1, r[0]);
            y1 = Math.min(y1, r[1]);
            x2 = Math.max(x2, r[2]);
            y2 = Math.max(y2, r[3]);
            area+=(r[2]-r[0])*(r[3]-r[1]);
        }
        System.out.println(area);
        System.out.println((x2-x1)*(y2-y1));
        if(area!=(x2-x1)*(y2-y1)) return false;
        int count = 0;
        for(int[] r:rectangles){
            if(r[0]==x1&&r[1]==y1) count++;
            else if(r[2]==x2&&r[3]==y2) count++;
        }
        System.out.println(x1+" "+y1+" "+x2+" "+y2);
        System.out.println(count);
        return count==2||count>=rectangles.length;
    }
}
  • 面积相等

  • 除顶点外所有方块的点出现了偶数次,完美拼接

public class Solution {
    public boolean isRectangleCover(int[][] rectangles) {
        // two conditions
        // 1.the area of large rectangle and the sum area of small rectangles
        // 2.every points should appear even times except 4 corners
        HashSet<String> set = new HashSet<String>();
        int area = 0;
        int x1 = Integer.MAX_VALUE, x2 = Integer.MIN_VALUE, y1 = Integer.MAX_VALUE, y2 = Integer.MIN_VALUE;
        for(int i=0;i<rectangles.length;i++){
            x1 = Math.min(x1, rectangles[i][0]);
            y1 = Math.min(y1, rectangles[i][1]);
            x2 = Math.max(x2, rectangles[i][2]);
            y2 = Math.max(y2, rectangles[i][3]);

            area += (rectangles[i][2]-rectangles[i][0]) * (rectangles[i][3]-rectangles[i][1]);

            String s1 = rectangles[i][0] + " " + rectangles[i][1];
            String s2 = rectangles[i][0] + " " + rectangles[i][3];
            String s3 = rectangles[i][2] + " " + rectangles[i][1];
            String s4 = rectangles[i][2] + " " + rectangles[i][3];
            if(!set.add(s1)) set.remove(s1);
            if(!set.add(s2)) set.remove(s2);
            if(!set.add(s3)) set.remove(s3);
            if(!set.add(s4)) set.remove(s4);
        }
         if (!set.contains(x1 + " " + y1) || !set.contains(x1 + " " + y2) || !set.contains(x2 + " " + y1) || !set.contains(x2 + " " + y2) || set.size() != 4) return false;

        return area == (x2-x1) * (y2-y1);
    }
}

Convex Polygon

高中数学,掌握算内积的方式,(BAx * BCy - BAy * BCx)。内积全正全负return false

public class Solution {
    public boolean isConvex(List<List<Integer>> points) {
        // For each set of three adjacent points A, B, C, find the cross product AB · BC. If the sign of
        // all the cross products is the same, the angles are all positive or negative (depending on the
        // order in which we visit them) so the polygon is convex.
        boolean gotNegative = false;
        boolean gotPositive = false;
        int numPoints = points.size();
        int B, C;
        for (int A = 0; A < numPoints; A++) {
            // Trick to calc the last 3 points: n - 1, 0 and 1.
            B = (A + 1) % numPoints;
            C = (B + 1) % numPoints;

            int crossProduct =
                crossProductLength(
                    points.get(A).get(0), points.get(A).get(1),
                    points.get(B).get(0), points.get(B).get(1),
                    points.get(C).get(0), points.get(C).get(1));
            if (crossProduct < 0) {
                gotNegative = true;
            }
            else if (crossProduct > 0) {
                gotPositive = true;
            }
            if (gotNegative && gotPositive) return false;
        }

        // If we got this far, the polygon is convex.
        return true;
    }

    // Return the cross product AB x BC.
    // The cross product is a vector perpendicular to AB and BC having length |AB| * |BC| * Sin(theta) and
    // with direction given by the right-hand rule. For two vectors in the X-Y plane, the result is a
    // vector with X and Y components 0 so the Z component gives the vector's length and direction.
    private int crossProductLength(int Ax, int Ay, int Bx, int By, int Cx, int Cy)
    {
        // Get the vectors' coordinates.
        int BAx = Ax - Bx;
        int BAy = Ay - By;
        int BCx = Cx - Bx;
        int BCy = Cy - By;

        // Calculate the Z coordinate of the cross product.
        return (BAx * BCy - BAy * BCx);
    }
}

Construct the Rectangle

public class Solution {
    public int[] constructRectangle(int area) {
        int x = (int)Math.sqrt((double)area);

        for(int i=x;i>=0;i--){
            if(area%i==0){
                return new int[]{area/i, i};
            }
        }
        return new int[2];
    }
}

Two Rectangles Overlap

Rectangle Area

这两个题放到一起,一个道理。在判断两个长方形有重合,那么两个长方形左边界的最大值一定小于右边界的最小值。两个长方形上边界的最小值一定大于下边界的最大值。

重合面积是(右边界min-左边界max)*(上边界min-下边界max)。不需要考虑两个长方形的相对位置,判断大小即可。

public class Solution {
    public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
        int x1 = Math.max(A,E);
        int y1 = Math.max(B,F);

        int x2 = Math.min(C,G);
        int y2 = Math.min(D,H);

        int ol = 0;
        if(x2<=x1 || y2<=y1) ol = 0;
        else ol = (x2-x1)*(y2-y1);

        return (C-A)*(D-B) + (G-E)*(H-F) - ol;
    }
}

results matching ""

    No results matching ""