问题描述
给你 二维 平面上两个 由直线构成且边与坐标轴平行/垂直 的矩形,请你计算并返回两个矩形覆盖的总面积。
每个矩形由其 左下 顶点和 右上 顶点坐标表示:
第一个矩形由其左下顶点 (ax1, ay1) 和右上顶点 (ax2, ay2) 定义。
第二个矩形由其左下顶点 (bx1, by1) 和右上顶点 (bx2, by2) 定义。
解题思路
如上图所示,两个矩形可以出现的3种情况:
- 两个矩形相交;
- 两个矩形完全独立;
- 两个矩形是包含关系。
代码实现
按照上述代码可以有以下代码实现:
public class Solution {
public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
int v1 = (ax2 - ax1) * (ay2 - ay1);
int v2 = (bx2 - bx1) * (by2 - by1);
// ax1<=ax2<=bx1<=bx2
// ay1<=ay2<=by1<=by2
// bx1<=bx2<=ax1<=ax2
// by1<=by2<=ay1<=ay2
if (ax2 <= bx1 || ay2 <= by1 || bx2 <= ax1 || by2 <= ay1) {
return v1 + v2;
} else if (ax1 <= bx1 && bx2 <= ax2 && ay1 <= by1 && by2 <= ay2 || bx1 <= ax1 && ax2 <= bx2 && by1 <= ay1 && ay2 <= by2) {
// ax1< bx1 < bx2< ax2
// ay1< by1 < by2< ay2
// bx1< ax1 < ax2< bx2
// by1< ay1 < ay2< by2
// 这里还要考虑部分包含的情况
return Math.max(v1, v2);
} else {
return v1 + v2 - cal(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2);
}
}
int cal(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
int x = 0;
if (ax1 <= bx1 && bx2 <= ax2) {
x = bx2 - bx1;
} else if (bx1 <= ax1 && ax2 <= bx2) {
x = ax2 - ax1;
} else if (ax1 < bx1 && bx1 < ax2) {
x = ax2 - bx1;
} else if (bx1 < ax1 && ax1 < bx2) {
x = bx2 - ax1;
}
int y = 0;
if (ay1 <= by1 && by2 <= ay2) {
y = by2 - by1;
} else if (by1 <= ay1 && ay2 <= by2) {
y = ay2 - ay1;
} else if (ay1 < by1 && by1 < ay2) {
y = ay2 - by1;
} else if (by1 < ay1 && ay1 < by2) {
y = by2 - ay1;
}
return x * y;
}
public static void main(String[] args) {
Solution solution = new Solution();
// System.out.println(solution.computeArea(-3, 0, 3, 4, 0, -1, 9, 2));
System.out.println(solution.computeArea(-2, -2, 2, 2, -3, -3, 3, -1));
}
}
总结
这个代码我这边实现还是很复杂的,分支特别多,整体耗时还是比较低的。看过其他代码实现,通过查看其他代码有更加简洁的实现。
思路如下:
- 分别求两个矩形的面积,分别是v1和v2;
- 求可能存在的重叠部分,
- int width = Math.min(ax2, bx2);
- int height = Math.max(ax1, ax2);
- 如果width > 0 并且 height > 0, 则重叠部分面积是 width * height,否则就是0;
- 返回v1+v2 - 重叠部分面积。
代码实现如下:
public class Solution {
public int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
int v1 = (ax2 - ax1) * (ay2 - ay1);
int v2 = (bx2 - bx1) * (by2 - by1);
int width = Math.min(ax2, bx2) - Math.max(ax1, bx1);
int height = Math.min(ay2, by2) - Math.max(ay1, by1);
int overlapArea = 0;
if (width > 0 && height > 0) {
overlapArea = width * height;
}
return v1 + v2 - overlapArea;
}
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.computeArea(-2, -2, 2, 2, -3, -3, 3, -1));
}
}