You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在列表内部区间可重叠时高效查找两区间列表的交集

解决内部有重叠区间的两列表重叠对查找问题

核心思路

由于原始双指针方法仅适用于内部无重叠的区间列表,针对内部有重叠的场景,我们可以先对两个列表分别合并重叠区间,同时记录每个合并区间对应的原始区间索引;再用经典双指针法找出合并后区间的重叠对;最后将合并区间对应的所有原始区间进行配对,得到所有符合要求的重叠区间对。这种方法的时间复杂度为O(n log n + m log m + k)(n、m为两列表长度,k为最终重叠对数),远优于暴力O(nm)解法。

具体步骤

1. 合并重叠区间并记录原始索引

对每个列表,先按区间左端点排序,再合并重叠/相邻区间,同时记录每个合并区间对应的原始区间索引列表。这样可以将内部重叠的区间转化为无重叠的合并区间,适配经典双指针法。

2. 双指针查找合并区间的重叠对

使用经典双指针法遍历两个合并后的无重叠区间列表,找出所有重叠的合并区间对。

3. 映射回原始区间对

对于每一对重叠的合并区间,将它们对应的所有原始区间进行两两配对,这些配对就是原始列表中所有的重叠区间对。

代码实现(Python)

def merge_with_indices(intervals):
    # 为区间添加原始索引并按左端点排序
    indexed_intervals = sorted(
        [(interval[0], interval[1], idx) for idx, interval in enumerate(intervals)],
        key=lambda x: x[0]
    )
    if not indexed_intervals:
        return [], []
    
    merged = []
    indices_map = []
    current_s, current_e, current_indices = indexed_intervals[0][0], indexed_intervals[0][1], [indexed_intervals[0][2]]
    
    for s, e, idx in indexed_intervals[1:]:
        if s <= current_e:
            # 重叠则合并区间,追加原始索引
            current_e = max(current_e, e)
            current_indices.append(idx)
        else:
            # 不重叠则保存当前合并结果
            merged.append((current_s, current_e))
            indices_map.append(current_indices)
            current_s, current_e, current_indices = s, e, [idx]
    
    # 保存最后一组合并结果
    merged.append((current_s, current_e))
    indices_map.append(current_indices)
    return merged, indices_map

def find_merged_overlaps(merged_a, merged_b):
    i = j = 0
    overlaps = []
    while i < len(merged_a) and j < len(merged_b):
        a_s, a_e = merged_a[i]
        b_s, b_e = merged_b[j]
        
        if a_e < b_s:
            # a区间无法和b的后续区间重叠,移动a指针
            i += 1
        elif b_e < a_s:
            # b区间无法和a的后续区间重叠,移动b指针
            j += 1
        else:
            # 记录重叠的合并区间索引对
            overlaps.append((i, j))
            # 移动右端点较小的区间指针
            if a_e <= b_e:
                i += 1
            else:
                j += 1
    return overlaps

def find_all_overlap_pairs(A, B):
    # 合并区间并获取原始索引映射
    merged_a, idx_map_a = merge_with_indices(A)
    merged_b, idx_map_b = merge_with_indices(B)
    
    # 查找合并区间的重叠对
    merged_overlaps = find_merged_overlaps(merged_a, merged_b)
    
    # 生成所有原始区间重叠对
    result = []
    for a_merge_idx, b_merge_idx in merged_overlaps:
        a_original_indices = idx_map_a[a_merge_idx]
        b_original_indices = idx_map_b[b_merge_idx]
        # 两两配对原始区间
        for a_idx in a_original_indices:
            for b_idx in b_original_indices:
                # 若需要返回区间本身则用(A[a_idx], B[b_idx]),返回索引则用(a_idx, b_idx)
                result.append((A[a_idx], B[b_idx]))
    return result

正确性说明

  • 合并后的区间是原始重叠区间的并集,若两个合并区间重叠,则它们对应的所有原始区间两两之间必然重叠;
  • 反之,若原始列表中的两个区间重叠,则它们所属的合并区间必然重叠,不会遗漏任何有效配对。

内容的提问来源于stack exchange,提问作者dimitris_ioan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:19:55