leetcode391. Perfect Rectangle

栏目: 编程工具 · 发布时间: 4年前

题目要求

Given N axis-aligned rectangles where N > 0, determine if they all together form an exact cover of a rectangular region.

Each rectangle is represented as a bottom-left point and a top-right point. For example, a unit square is represented as [1,1,2,2]. (coordinate of bottom-left point is (1, 1) and top-right point is (2, 2)).

Example 1:

rectangles = [
  [1,1,3,3],
  [3,1,4,2],
  [3,2,4,4],
  [1,3,2,4],
  [2,3,3,4]
]

Return true. All 5 rectangles together form an exact cover of a rectangular region.

leetcode391. Perfect Rectangle

Example 2:

rectangles = [
  [1,1,2,3],
  [1,3,2,4],
  [3,1,4,2],
  [3,2,4,4]
]

Return false. Because there is a gap between the two rectangular regions.

leetcode391. Perfect Rectangle

Example 3:

rectangles = [
  [1,1,3,3],
  [3,1,4,2],
  [1,3,2,4],
  [3,2,4,4]
]

Return false. Because there is a gap in the top center.

leetcode391. Perfect Rectangle

Example 4:

rectangles = [
  [1,1,3,3],
  [3,1,4,2],
  [1,3,2,4],
  [2,2,4,4]
]

Return false. Because two of the rectangles overlap with each other.

leetcode391. Perfect Rectangle

用一个二维数组来表示一堆矩形,二维数组中的每一行分别记录矩形左下角和右上角的坐标。试判断这些矩形拼接成的新的图形是否还是一个矩形。如果矩形存在重合,则不构成矩形,见图例4.

思路和代码

这是一道纯粹的考验思维的一道题目。

首先我们知道,这些矩形如果能够拼接成一个大的矩形,那么大的矩形的左下角坐标一定是所有矩形中最小的x1和y1值构成的,同理,右上角坐标一定是由最大的x2和y2的值构成的。该理想情况下矩形的面积应当等于所有矩形的面积之和。一旦不相等,则一定无法构成大的矩形。

其次,光判断面积并不足够,可以这样三个矩形构成的图形 [1,1,2,2],[2,2,3,3],[2,1,3,3] 。可以看到该图形的理想矩形就是一个 2*2 的正方形,它的面积与所有的小矩形的和相等,但是这些小矩形并没有构成该理想的矩形。那么我们能用什么方式来过滤掉这种矩形呢。只能从矩形的顶点入手了。

我们知道,任何一个能够构成理想矩形的小矩形,一定会有顶点的重合,直到只剩下四个重合度为1的点,即大矩形的四个顶点。其它的所有顶点都应当有另一个矩形与其重合。因此我们只需要留下所有度为1的顶点,判断其是否都是大矩形的四个顶点即可。

代码如下:

public boolean isRectangleCover(int[][] rectangles) {
        if(rectangles==null || rectangles.length == 0 || rectangles[0].length == 0) return false;
        int areaSum = 0;
        int x1 = Integer.MAX_VALUE;
        int x2 = Integer.MIN_VALUE;
        int y1 = Integer.MAX_VALUE;
        int y2 = Integer.MIN_VALUE;
        
        Set<String> points = new HashSet<>(rectangles.length * 4);
        for(int[] rectangle : rectangles) {
            x1 = Math.min(rectangle[0], x1);
            x2 = Math.max(rectangle[2], x2);
            y1 = Math.min(rectangle[1], y1);
            y2 = Math.max(rectangle[3], y2);
            
            areaSum += (rectangle[0] - rectangle[2]) * (rectangle[1] - rectangle[3]);
            String s1 = rectangle[0] + " " + rectangle[1];
            String s2 = rectangle[0] + " " + rectangle[3];
            String s3 = rectangle[2] + " " + rectangle[1];
            String s4 = rectangle[2] + " " + rectangle[3];
            if (!points.add(s1)) {
                points.remove(s1);
            }
            if (!points.add(s2)) {
                points.remove(s2);
            }
            if (!points.add(s3)) {
                points.remove(s3);
            }
            if (!points.add(s4)) {
                points.remove(s4);
            }
        }
        if(!points.contains(x1 + " " + y1) || 
                !points.contains(x1 + " " + y2) ||
                !points.contains(x2 + " " + y1) ||
                !points.contains(x2 + " " + y2) ||
                points.size() != 4) return false;
        return areaSum == (x2 - x1) * (y2 - y1);
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

跨越

跨越

Lydia / 人民文学出版社 / 2018-4-1 / 39

三跨青年Lydia的一线奋斗笔记,抛却艰深理论,用亲身经验为你打通任督二脉。 揭开思维认知盲区,剖析成长潜在技巧,探知进阶背后逻辑,在拐点到来的时刻,推动人生加速上行。 10大职场潜在成长技巧,13种打破思维认知的的碎片重建,15种正确面对情感的能量释放, 38篇有世界 观,有方法论的故事,为你打开上升通道。 停留在思维层面的改变人生,其实已然陷入困境, 人生上行的实......一起来看看 《跨越》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

SHA 加密
SHA 加密

SHA 加密工具