391. 完美矩形
给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是 (ai, bi) 。
如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回 false 。
1 <= rectangles.length <= 2 * 104
rectangles[i].length == 4
-105 <= xi, yi, ai, bi <= 105
示例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
解释:因为中间有相交区域,虽然形成了矩形,但不是精确覆盖。
代码:
class Solution {
public boolean isRectangleCover(int[][] r) {
//只有4个奇数次出现的坐标/
// 面积相等
int left = Integer.MAX_VALUE;
int right = Integer.MIN_VALUE;
int top = Integer.MIN_VALUE;
int bottom = Integer.MAX_VALUE;
int n = r.length;
Set<String>set = new HashSet<>();
int sum = 0; // 小矩形相加
for(int i = 0; i < n; i++){
int []t = r[i];
//更新大矩形四个点坐标
left = Math.min(left, t[0]);
bottom = Math.min(bottom, t[1]);
right = Math.max(right, t[2]);
top = Math.max(top, t[3]);
//计算小矩形面积
sum += (caculateArea(t[0], t[1], t[2], t[3]));
//记录坐标
String [] strings = new String[4];
// 小矩形四个点坐标
strings[0] = merge(t[0], t[1]);
strings[1] = merge(t[0], t[3]);
strings[2] = merge(t[2], t[1]);
strings[3] = merge(t[2], t[3]);
// 出现偶数次的抵消,奇数次保留
for(int j = 0; j < 4; j++){
if(set.contains(strings[j]))set.remove(strings[j]);
else set.add(strings[j]);
}
}
//最后必须只剩4个点并且set中的4个点与大矩形4个点坐标对应才表示位置匹配
if(set.size() == 4 &&
set.contains(merge(left, top)) &&
set.contains(merge(left, bottom)) &&
set.contains(merge(right, top))&&
set.contains(merge(right, bottom))
){
return sum == caculateArea(left, bottom, right, top);// 面积相等即可
}
return false;
}
int caculateArea(int left, int bottom, int right, int top){
return (top - bottom) * (right - left);
}
String merge(int a, int b){
return a + " " + b;
}
}
执行结果:
总结: LeetCode打卡第二十一天,通过每天做题可以看到自己的不足,提升自己的能力,在做题中慢慢进步,但是代码编程能力还有待提高,还需要继续加油!