391. 完美矩形

题目

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/perfect-rectangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是 (ai, bi) 。

如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回 false 。

示例

 

输入:rectangles = [[1,1,3,3],[3,1,4,2],[3,2,4,4],[1,3,2,4],[2,3,3,4]]
输出:true
解释:5 个矩形一起可以精确地覆盖一个矩形区域。 

解题思路

作者:himymBen
链接:https://leetcode-cn.com/problems/perfect-rectangle/solution/pythonjavajavascriptgo-tong-ji-mei-ge-di-x3ub/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

我们考虑拼出完美矩形的情况:

左下角、左上角、右下角、右上角的顶点一定是所有矩阵的最外圈
它们的面积和一定和完美矩阵的面积相等
任意不是这四个顶点的小矩阵的点,一定会出现两次或四次(如果出现四次以上,一定有超过四个矩阵以这个点为顶点,那么必然有重叠;如果出现奇数次,那么必然没有被完整覆盖)【这个的判断可以去掉面积相等,但是是内部重叠的情况】

/**
 * @param {number[][]} rectangles
 * @return {boolean}
 */
var point = function(x, y){
    return 10001 * x + y;
}

var isRectangleCover = function(rectangles) {
    let x = 10001, y = 10001, a = -10001, b = -10001, s = 0;
    cnts = new Map();
    for(const r of rectangles){
        x = Math.min(x, r[0]);
        y = Math.min(y, r[1]);
        a = Math.max(a, r[2]);
        b = Math.max(b, r[3]);
        s += (r[3] - r[1]) * (r[2] - r[0]);
        const p1 = point(r[0], r[1]), p2 = point(r[0],r[3]), p3 = point(r[2], r[1]), p4 = point(r[2],r[3]);
        if(cnts.has(p1))
            cnts.set(p1, cnts.get(p1) + 1);
        else
            cnts.set(p1, 1);
        if(cnts.has(p2))
            cnts.set(p2, cnts.get(p2) + 1);
        else
            cnts.set(p2, 1);
        if(cnts.has(p3))
            cnts.set(p3, cnts.get(p3) + 1);
        else
            cnts.set(p3, 1);
        if(cnts.has(p4))
            cnts.set(p4, cnts.get(p4) + 1);
        else
            cnts.set(p4, 1);
    }
    if(s != (a - x) * (b - y))
        return false;
    const points = new Set();
    points.add(point(x, y)); 
    points.add(point(x, b));
    points.add(point(a, y));
    points.add(point(a, b));
    for(const p of points){
        if(!cnts.has(p) || cnts.get(p) != 1){
            return false;
        }
    }
    for(const p of cnts.keys()){
        if(!points.has(p)){
            const v = cnts.get(p);
            if(v > 4 || v % 2 != 0)
                return false;
        }
    }
    return true;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值