Medium
题目描述
给你二维平面上两个 由直线构成且边与坐标轴平行/垂直 的矩形,请你计算并返回两个矩形覆盖的总面积。
每个矩形由其 左下 顶点和 右上 顶点坐标表示:
- 第一个矩形由其左下顶点
(ax1, ay1)和右上顶点(ax2, ay2)定义。 - 第二个矩形由其左下顶点
(bx1, by1)和右上顶点(bx2, by2)定义。
示例 1:
输入:ax1 = -3, ay1 = 0, ax2 = 3, ay2 = 4, bx1 = 0, by1 = -1, bx2 = 9, by2 = 2
输出:45
示例 2:
输入:ax1 = -2, ay1 = -2, ax2 = 2, ay2 = 2, bx1 = -2, by1 = -2, bx2 = 2, by2 = 2
输出:16
提示:
-10^4 <= ax1 <= ax2 <= 10^4-10^4 <= ay1 <= ay2 <= 10^4-10^4 <= bx1 <= bx2 <= 10^4-10^4 <= by1 <= by2 <= 10^4
解题思路
解题思路
这道题的核心思想是利用容斥原理:总覆盖面积 = 矩形A面积 + 矩形B面积 - 重叠部分面积。
关键步骤:
计算两个矩形的面积:矩形面积 = 长 × 宽,即
(x2-x1) × (y2-y1)计算重叠矩形的面积:
- 重叠矩形的左下角坐标:
(max(ax1, bx1), max(ay1, by1)) - 重叠矩形的右上角坐标:
(min(ax2, bx2), min(ay2, by2)) - 如果重叠矩形的左下角在右上角的右边或上边,说明两矩形不重叠,重叠面积为0
- 重叠矩形的左下角坐标:
应用容斥原理:用两个矩形面积之和减去重叠面积
边界情况处理:
- 两矩形完全不重叠:重叠面积为0
- 两矩形完全重合:重叠面积等于矩形面积
- 一个矩形包含另一个:重叠面积等于较小矩形面积
算法时间复杂度为O(1),空间复杂度为O(1),是最优解法。
代码实现
class Solution {
public:
int computeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
// 计算两个矩形的面积
int areaA = (ax2 - ax1) * (ay2 - ay1);
int areaB = (bx2 - bx1) * (by2 - by1);
// 计算重叠部分的左下角和右上角坐标
int overlapLeft = max(ax1, bx1);
int overlapRight = min(ax2, bx2);
int overlapBottom = max(ay1, by1);
int overlapTop = min(ay2, by2);
// 计算重叠面积
int overlapArea = 0;
if (overlapLeft < overlapRight && overlapBottom < overlapTop) {
overlapArea = (overlapRight - overlapLeft) * (overlapTop - overlapBottom);
}
return areaA + areaB - overlapArea;
}
};
class Solution:
def computeArea(self, ax1: int, ay1: int, ax2: int, ay2: int, bx1: int, by1: int, bx2: int, by2: int) -> int:
# 计算两个矩形的面积
area_a = (ax2 - ax1) * (ay2 - ay1)
area_b = (bx2 - bx1) * (by2 - by1)
# 计算重叠部分的左下角和右上角坐标
overlap_left = max(ax1, bx1)
overlap_right = min(ax2, bx2)
overlap_bottom = max(ay1, by1)
overlap_top = min(ay2, by2)
# 计算重叠面积
overlap_area = 0
if overlap_left < overlap_right and overlap_bottom < overlap_top:
overlap_area = (overlap_right - overlap_left) * (overlap_top - overlap_bottom)
return area_a + area_b - overlap_area
public class Solution {
public int ComputeArea(int ax1, int ay1, int ax2, int ay2, int bx1, int by1, int bx2, int by2) {
// 计算两个矩形的面积
int areaA = (ax2 - ax1) * (ay2 - ay1);
int areaB = (bx2 - bx1) * (by2 - by1);
// 计算重叠部分的左下角和右上角坐标
int overlapLeft = Math.Max(ax1, bx1);
int overlapRight = Math.Min(ax2, bx2);
int overlapBottom = Math.Max(ay1, by1);
int overlapTop = Math.Min(ay2, by2);
// 计算重叠面积
int overlapArea = 0;
if (overlapLeft < overlapRight && overlapBottom < overlapTop) {
overlapArea = (overlapRight - overlapLeft) * (overlapTop - overlapBottom);
}
return areaA + areaB - overlapArea;
}
}
var computeArea = function(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) {
// 计算两个矩形的面积
const areaA = (ax2 - ax1) * (ay2 - ay1);
const areaB = (bx2 - bx1) * (by2 - by1);
// 计算重叠部分的左下角和右上角坐标
const overlapLeft = Math.max(ax1, bx1);
const overlapRight = Math.min(ax2, bx2);
const overlapBottom = Math.max(ay1, by1);
const overlapTop = Math.min(ay2, by2);
// 计算重叠面积
let overlapArea = 0;
if (overlapLeft < overlapRight && overlapBottom < overlapTop) {
overlapArea = (overlapRight - overlapLeft) * (overlapTop - overlapBottom);
}
return areaA + areaB - overlapArea;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(1) | 只需要进行常数次数学运算 |
| 空间复杂度 | O(1) | 只使用了常数个变量存储中间结果 |