两个矩形是否重叠如何用投影区间判断?(LeetCode 836)
简化版
两个轴对齐矩形重叠,等价于它们在 x 轴投影有正长度交集,并且在 y 轴投影也有正长度交集。若一个矩形在另一个左边、右边、上边或下边,就不重叠;否则重叠。边界接触不算重叠,因为面积为 0。
详细版
矩形用 [x1,y1,x2,y2] 表示左下和右上角:
boolean isRectangleOverlap(int[] rec1, int[] rec2) {
return rec1[0] < rec2[2] &&
rec2[0] < rec1[2] &&
rec1[1] < rec2[3] &&
rec2[1] < rec1[3];
}
也可以写成“排除不重叠”:
return !(rec1[2] <= rec2[0] || rec2[2] <= rec1[0]
|| rec1[3] <= rec2[1] || rec2[3] <= rec1[1]);
注意用 < 而不是 <= 来保证交集长度为正。
完整版教学
一、重叠面积来自两个方向
轴对齐矩形的面积重叠,必须同时满足:
x 方向有正长度交集
y 方向有正长度交集
只在 x 方向重合但 y 方向分开,面积为 0;只在边界接触,面积也为 0。
二、先看一维区间重叠
两个开面积意义下的一维区间 [a1,a2] 和 [b1,b2] 有正长度交集,当且仅当:
a1 < b2 && b1 < a2
| 区间 A | 区间 B | 是否正重叠 |
|---|---|---|
[0,2] | [1,3] | 是 |
[0,1] | [1,2] | 否 |
[2,4] | [0,1] | 否 |
易错点:边界相等只是接触,不是有正长度交集,所以判断用
<。
三、矩形投影到两个轴
矩形 [x1,y1,x2,y2] 在 x 轴上的投影是 [x1,x2],在 y 轴上的投影是 [y1,y2]。
因此重叠条件是:
rec1.x1 < rec2.x2
rec2.x1 < rec1.x2
rec1.y1 < rec2.y2
rec2.y1 < rec1.y2
四个条件都成立,两个方向都有正长度交集。
四、排除法也很好记
不重叠只有四种情况:
rec1 在 rec2 左边
rec1 在 rec2 右边
rec1 在 rec2 下边
rec1 在 rec2 上边
代码就是把这四种情况或起来,再取反。
五、边界接触为什么不算
题目通常要求“面积大于 0”。如果两个矩形只共享一条边:
rec1.x2 == rec2.x1
x 方向交集长度为 0,面积自然是 0。此时不能返回 true。
六、复杂度与泛化
判断只需要常数次比较,时间 O(1),空间 O(1)。
如果矩形不是轴对齐的,就不能只看 x/y 投影,需要使用分离轴定理等几何方法;但本题明确是轴对齐矩形。
七、常见误区与追问
- 误区:边界接触算重叠。 面积为 0,题目通常不算。
- 误区:只判断一个方向。 矩形面积重叠必须两个轴都有交集。
- 误区:把
<写成<=。 会把贴边情况误判成重叠。 - 追问:为什么投影交集能判断矩形重叠? 轴对齐矩形是两个一维区间的笛卡尔积。
- 追问:复杂度是多少? 常数次比较,
O(1)。 - 追问:非轴对齐矩形怎么办? 需要更一般的几何碰撞检测,如分离轴定理。
八、加强记忆
矩形重叠先降维成区间重叠:x 有正交集,y 有正交集。公式记成 left1 < right2 && left2 < right1,两个轴各来一次。只要题目说面积大于 0,贴边就不是重叠。