如何快速检测两个无序区间的相交性(含包含不含完全重合)
快速检测两个区间是否相交的优化方法
问题说明
给定两个区间(x1, x2)和(z1, z2),需要判断它们是否相交,判断规则如下:
- 一个区间被另一个完全包含时,视为相交(例如
(2,5)与(3,4)、(2,5)与(3,5)、(2,5)与(2,4)都算相交) - 两个区间完全重合时,不算相交(例如
(2,5)与(2,5)不算) - 输入的区间可能是无序的(比如端点颠倒的
(x2, x1)或(z2, z1)) - 判断仅使用
<、>运算符,不使用<=、>=
最初的判断逻辑分支较多,示例如下:
if # 示例情况:(2,4) 和 (3,6) x1 > z1 < x2 and (z2 < x1 or z2 > x2) or # 示例情况:(2,4) 和 (1,3) x1 > z2 < x2 and (z1 < x1 or z1 > x2) or # 示例情况:(3,6) 和 (2,4)(交换x、z后的第一种情况) ............. reverse(1) x <--> z or # 示例情况:(1,3) 和 (2,4)(交换x、z后的第二种情况) ............. reverse(2) x <--> z
需要更简洁高效的判断方法。
优化后的实现方案
以下是步骤更少、逻辑更清晰的实现,同时处理了区间无序、单点区间等特殊情况:
def olap(x1, x2, z1, z2): # 单点区间(两端点相等)直接判定为相交 if x1 == x2 or z1 == z2: return True # 完全重合的区间,按规则判定为不相交(原代码此处返回True为疑似笔误,已修正) if x1 == z1 and x2 == z2: return False # 将两个区间调整为左端点 < 右端点的有序形式 if x1 > x2: x1, x2 = x2, x1 if z1 > z2: z1, z2 = z2, z1 # 交换区间顺序,确保x区间的左端点更小或覆盖范围更靠左 if x1 > z1 or x2 > z2: z1, z2, x1, x2 = x1, x2, z1, z2 # 核心判断:z区间的左端点落在x区间内,且z区间的右端点不被x区间完全包含 return x1 < z1 < x2 and (z2 < x1 or z2 > x2)
逻辑说明
- 特殊情况优先处理:先判断单点区间(直接相交)和完全重合区间(直接不相交)
- 统一区间格式:把所有区间调整为左端点小于右端点的有序状态,避免无序输入的干扰
- 标准化区间顺序:交换两个区间,让x区间处于更靠左的位置,减少后续判断的分支
- 核心相交判断:通过一次条件判断覆盖所有相交(非重合)的情况
内容的提问来源于stack exchange,提问作者sten
相关产品推荐
相关产品推荐

