Rectangle Overlap

  • 836
  • Easy

题目的两个核心关键:

  • 矩形各边都平行于坐标轴(Axis-aligned)。
  • 重叠必须有正面积:只贴边、只蹭角都不算。

因为边平行于坐标轴,二维相交就可以直接拆成两次独立的一维区间相交:

  • x 轴投影:rec1 的 [x1, x2] 与 rec2 的 [x1, x2] 是否重合?
  • y 轴投影:rec1 的 [y1, y2] 与 rec2 的 [y1, y2] 是否重合?

只有两个轴上的投影都有交集,平面上才会交叠出一块长、宽都大于 0 的矩形。

如何判断一维区间相交?

设两条线段分别为 [a1, a2] 与 [b1, b2](保证左端点小于右端点)。

从反面看更直观——线段在数轴上完全错开只有两种情况:

  • A 在 B 的左侧:a2 <= b1
  • A 在 B 的右侧:a1 >= b2

把「不相交」取反,即得到重叠条件:

!(a2 <= b1 || a1 >= b2)

根据德摩根定律化简,得到:

a1 < b2 && b1 < a2

题目要求重叠面积必须大于 0。如果边缘刚好贴合(例如 a2 == b1),重叠宽度就是 0;这里的严格小于号 < 刚好把贴边和碰角自然过滤掉。

算法逻辑:

input rec1, rec2

// rec = [x1, y1, x2, y2]
// 严格小于:贴边时长度为 0,判定为 false
x_hit = rec1[0] < rec2[2] && rec2[0] < rec1[2]
y_hit = rec1[1] < rec2[3] && rec2[1] < rec1[3]

return x_hit && y_hit

代码实现:

function isRectangleOverlap(rec1, rec2) {
  return rec1[0] < rec2[2] && rec2[0] < rec1[2]
    && rec1[1] < rec2[3] && rec2[1] < rec1[3]
}