题目来源:https://leetcode-cn.com/problems/perfect-rectangle/
大致题意:
给定一组矩阵的坐标(左下角和右上角),判断这些矩阵是否完整的拼成另一个大矩阵,并且不能有重合
如:

思路
若想让给定的小矩阵组成大矩阵,需要满足以下条件:
- 小矩阵的面积和等于大矩阵的面积
- 可知每个矩阵有四个角,大矩阵由小矩阵组成,在小矩阵的所有角的坐标中,构成大矩阵的角的坐标只出现一次(否则会有重叠),而大矩阵内部的小矩阵的角坐标出现次数为 2 或 4。若为其它数,则一定是大矩阵内部有小矩阵未覆盖的区域,或者是有小矩阵重叠

于是可以通过遍历所有小矩阵,做以下操作:
- 统计小矩阵面积和
- 求出大矩阵的角坐标
- 求出所有小矩阵角坐标的出现次数
然后做以下判断:
- 大矩阵的面积是否等于小矩阵面积和
- 出现 1 次的坐标是不是边界坐标
- 其他坐标是不是出现 2 次或者 4 次
代码:
public boolean isRectangleCover(int[][] rectangles) {
// 大矩阵的左下角和右上角坐标
int leftBottomX = rectangles[0][0];
int leftBottomY = rectangles[0][1];
int rightTopX = rectangles[0][2];
int rightTopY = rectangles[0][3];
int areaSum = 0;
// 存坐标出现的次数
Map<String, Integer> point = new HashMap<>();
// 遍历小矩阵
for (int[] rectangle : rectangles) {
// 取出坐标
int x1 = rectangle[0];
int y1 = rectangle[1];
int x2 = rectangle[2];
int y2 = rectangle[3];
// 更新大矩阵的坐标
leftBottomX = Math.min(leftBottomX, x1);
leftBottomY = Math.min(leftBottomY, y1);
rightTopX = Math.max(rightTopX, x2);
rightTopY = Math.max(rightTopY, y2);
// 统计面积和
areaSum += (x2 - x1) * (y2 - y1);
// 统计坐标出现次数
String leftTop = point(x1, y2);
String leftBottom = point(x1, y1);
String rightTop = point(x2, y2);
String rightBottom = point(x2, y1);
point.put(leftBottom, point.getOrDefault(leftBottom, 0) + 1);
point.put(leftTop, point.getOrDefault(leftTop, 0) + 1);
point.put(rightBottom, point.getOrDefault(rightBottom, 0) + 1);
point.put(rightTop, point.getOrDefault(rightTop, 0) + 1);
}
int area = (rightTopX - leftBottomX) * (rightTopY - leftBottomY);
// 面积和是否等于大矩阵面积
if (area != areaSum) {
return false;
}
// 判断坐标出现次数是否合理
for (Map.Entry<String, Integer> entry : point.entrySet()) {
String[] curPoint = entry.getKey().split(",");
int x = Integer.valueOf(curPoint[0]);
int y = Integer.valueOf(curPoint[1]);
int count = entry.getValue();
switch (count) {
case 1:
// 出现 1 次时,若不是大矩阵角坐标
if (!((x == leftBottomX && y == leftBottomY) || (x == leftBottomX && y == rightTopY) ||
(x == rightTopX && y == rightTopY) || (x == rightTopX && y == leftBottomY))) {
return false;
}
break;
case 2:
// 出现 2 次时,若是大矩阵角坐标
if ((x == leftBottomX && y == leftBottomY) || (x == leftBottomX && y == rightTopY) ||
(x == rightTopX && y == rightTopY) || (x == rightTopX && y == leftBottomY)) {
return false;
}
break;
case 4:
break;
default:
return false;
}
}
return true;
}
// 将坐标转化为字符串
public String point(int x, int y) {
return String.format("%d,%d", x, y);
}
该博客主要探讨了一个算法问题,即如何判断一组给定的矩阵坐标是否能完整无重叠地拼成一个大矩阵。关键在于检查小矩阵的面积和、大矩阵的边界坐标以及所有坐标出现的次数。通过遍历所有小矩阵,统计面积和、更新大矩阵坐标及坐标出现次数,最后验证面积和、坐标出现次数的合理性来实现判断。
742

被折叠的 条评论
为什么被折叠?



