LeetCode #391 Perfect Rectangle 完美矩形

391 Perfect Rectangle 完美矩形

Description:
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:

Example 1:

rectangle_perfect

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.

Example 2:

rectangle_separated

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.

Example 3:

rectangle_hole

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.

Example 4:

rectangle_intersect

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.

题目描述:
我们有 N 个与坐标轴对齐的矩形, 其中 N > 0, 判断它们是否能精确地覆盖一个矩形区域。

每个矩形用左下角的点和右上角的点的坐标来表示。例如, 一个单位正方形可以表示为 [1,1,2,2]。 ( 左下角的点的坐标为 (1, 1) 以及右上角的点的坐标为 (2, 2) )。

示例 :

示例 1:

完美矩形

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

返回 true。5个矩形一起可以精确地覆盖一个矩形区域。

示例 2:

分隔矩形

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

返回 false。两个矩形之间有间隔,无法覆盖成一个矩形。

示例 3:

间隔矩形

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

返回 false。图形顶端留有间隔,无法覆盖成一个矩形。

示例 4:

相交矩形

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

返回 false。因为中间有相交区域,虽然形成了矩形,但不是精确覆盖。

思路:

如果是完美矩形, 则四个角只出现一次, 其他的点成对出现
用一个哈希表记录 4个顶点的位置, 记录所有的矩形的面积和
最后要留下 4个顶点, 且面积和等于最后形成的矩形
时间复杂度O(n), 空间复杂度O(n)

代码:
C++:

class Solution 
{
public:
    bool isRectangleCover(vector<vector<int>>& rectangles) 
    {
        set<pair<int,int>> s;
        int left = INT_MAX, bottom = INT_MAX, top = INT_MIN, right = INT_MIN, area = 0;
        for (auto &p : rectangles)
        {
            left = min(p[0], left);
            bottom = min(p[1], bottom);
            right = max(p[2], right);
            top = max(p[3],top);
            area += (p[2] - p[0]) * (p[3] - p[1]);
            vector<pair<int,int>> temp({make_pair(p[0], p[1]), make_pair(p[0], p[3]), make_pair(p[2], p[1]), make_pair(p[2], p[3])});
            for (auto point : temp)
            {
                if (s.count(point)) s.erase(point);
                else s.insert(point);
            }
        }
        if (s.size() == 4 and s.count(make_pair(left,bottom)) and s.count(make_pair(left,top)) and s.count(make_pair(right,top)) and s.count(make_pair(right,bottom)))
           return area == (right - left) * (top - bottom);
        return false;
    }
};

Java:

class Solution {
    public boolean isRectangleCover(int[][] rectangles) {
        int left = Integer.MAX_VALUE, right = Integer.MIN_VALUE, top = Integer.MIN_VALUE, bottom = Integer.MAX_VALUE, n = rectangles.length, area = 0;
        Set<String> set = new HashSet<>();
        for (int i = 0; i < n; i++) {
            left = Math.min(left, rectangles[i][0]);
            bottom = Math.min(bottom, rectangles[i][1]);
            right = Math.max(right, rectangles[i][2]);
            top = Math.max(top, rectangles[i][3]);
            area += (rectangles[i][3] - rectangles[i][1]) * (rectangles[i][2] - rectangles[i][0]);
            String a = rectangles[i][0] + " " + rectangles[i][3], b = rectangles[i][0] + " " + rectangles[i][1], c = rectangles[i][2] + " " + rectangles[i][3], d = rectangles[i][2] + " " + rectangles[i][1];
            if (set.contains(a)) set.remove(a);
            else set.add(a);
            if (set.contains(b)) set.remove(b);
            else set.add(b);
            if (set.contains(c)) set.remove(c);
            else set.add(c);
            if (set.contains(d)) set.remove(d);
            else set.add(d);
        }
        if (set.size() == 4 && set.contains(left + " " + top) && set.contains(left + " " + bottom) && set.contains(right + " " + bottom) && set.contains(right + " " + top)) return area == (right - left) * (top - bottom);
        return false;
    }
}

Python:

class Solution:
    def isRectangleCover(self, rectangles: List[List[int]]) -> bool:
        left, right, bottom, top, area, s = float('inf'), -float('inf'), float('inf'), -float('inf'), 0, set()
        for p in rectangles:
            left, right, bottom, top = min(left, p[0]), max(right, p[2]), min(bottom, p[1]), max(top, p[3])
            area += (p[2] - p[0]) * (p[3] - p[1])
            temp = [(p[0], p[1]), (p[0], p[3]), (p[2], p[1]), (p[2], p[3])]
            for point in temp:
                if point in s:
                    s.remove(point)
                else:
                    s.add(point)
        if len(s) == 4 and (left, bottom) in s and (left, top) in s and (right, top) in s and (right, bottom) in s:
            return area == (right - left) * (top - bottom)
        return False
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容