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

区间列表中非重叠对的最优计数:求优于O(n²)的解法

计数区间列表中的非重叠对数量

问题描述

给定一个区间列表,需要统计其中非重叠对的数量(即两个区间无交集,满足前一个区间的右端点小于后一个区间的左端点)。示例如下:

输入区间列表:

[(1, 8), (7, 9), (3, 10), (7, 12), (11, 13), (13, 14), (9, 15)]

对应的非重叠对共有8个:

((1, 8), (11, 13))
((1, 8), (13, 14))
((1, 8), (9, 15))
((7, 9), (11, 13))
((7, 9), (13, 14))
((3, 10), (11, 13))
((3, 10), (13, 14))
((7, 12), (13, 14))

当前采用暴力解法,通过两两比较所有区间实现,时间复杂度为O(n²),代码如下:

def count_non_overlapping_pairs(intervals):
    intervals = list(set(intervals))  # 去重
    intervals.sort(key=lambda x: x[1])
    pairs = 0
    for i in range(len(intervals)):
        for j in range(i+1, len(intervals)):
            if intervals[i][1] < intervals[j][0]:
                pairs += 1
    return pairs

询问是否存在更优的实现方案。


更优解法:O(n log n) 时间复杂度

当然存在更优方案,我们可以通过排序+二分查找将时间复杂度降至O(n log n),具体思路如下:

核心思路

  1. 去重与排序:先对区间去重,然后按区间的右端点从小到大排序。排序后,已处理过的区间的右端点会形成一个递增序列,方便后续二分查找。
  2. 遍历统计:遍历每个区间时,统计有多少个之前处理过的区间的右端点小于当前区间的左端点——这些区间都和当前区间构成非重叠对。利用二分查找可快速找到该数量,避免暴力遍历。
  3. 维护有序序列:由于按右端点排序,每次遍历的区间右端点都大于等于之前的,因此可直接将当前区间的右端点追加到有序列表中,无需额外排序操作。

代码实现

import bisect

def count_non_overlapping_pairs(intervals):
    # 去重(区间为元组,支持哈希去重)
    intervals = list(set(intervals))
    n = len(intervals)
    # 区间数量不足2时直接返回0
    if n < 2:
        return 0
    
    # 按区间右端点从小到大排序
    intervals.sort(key=lambda x: x[1])
    
    total_pairs = 0
    # 维护已处理区间的右端点有序列表
    processed_ends = []
    
    for start, end in intervals:
        # 用二分查找统计processed_ends中小于当前区间左端点的元素数量
        # bisect_left返回第一个大于等于start的位置,位置值即为小于start的元素个数
        valid_count = bisect.bisect_left(processed_ends, start)
        total_pairs += valid_count
        # 将当前区间的右端点追加到有序列表(因排序过,列表始终保持递增)
        processed_ends.append(end)
    
    return total_pairs

验证示例

用示例输入测试该函数:

  • 排序后的区间按右端点顺序为:(1,8), (7,9), (3,10), (7,12), (11,13), (13,14), (9,15)
  • 遍历每个区间时,统计的有效非重叠对数量依次为:0、0、0、0、3、4、1,总和为8,与示例结果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:45:14