You need to enable JavaScript to run this app. 统计满足i<j且array[i]>array[j]的数组逆序对的高效实现咨询
优惠活动
大模型
产品
解决方案
定价
更多

统计满足i<j且array[i]>array[j]的数组逆序对的高效实现咨询

大规模数组下逆序对计数的高效实现

原双重循环实现超时的根因

当前写法的时间复杂度为O(N²),当N达到1e5量级时,累计循环运算量可达1e10次,远超出Python等脚本语言的常规时间阈值,必然触发时间限制。

可适配N=1e5规模的实现思路

我们要统计的满足i < j且array[i] > array[j]的元素对,就是经典的数组逆序对。这类问题可以通过*O(N log N)*时间复杂度的算法解决,完全覆盖1e5的规模约束,主流实现方案包括:

  • 归并排序分治计数:在归并排序的区间合并环节,顺带统计跨区间的逆序对数量,不需要额外的全量遍历
  • 树状数组(Fenwick树)计数:先对数组元素做离散化压缩取值范围,从后往前遍历数组,动态查询已遍历元素中小于当前值的元素数量,累加得到总逆序对数

参考实现代码(树状数组版本)

# 树状数组基础实现
class FenwickTree:
    def __init__(self, size):
        self.tree = [0] * (size + 1)
    
    def update(self, pos, delta):
        while pos < len(self.tree):
            self.tree[pos] += delta
            pos += pos & -pos
    
    def query(self, pos):
        count = 0
        while pos > 0:
            count += self.tree[pos]
            pos -= pos & -pos
        return count

if __name__ == "__main__":
    n = int(input())
    arr = list(map(int, input().split()))
    # 对数组元素做离散化,压缩取值范围
    sorted_vals = sorted(set(arr))
    val_rank = {val: idx+1 for idx, val in enumerate(sorted_vals)}
    ft = FenwickTree(len(sorted_vals))
    total = 0
    # 从后往前遍历统计逆序对
    for num in reversed(arr):
        rank = val_rank[num]
        # 累加已经出现的、比当前值小的元素数量
        total += ft.query(rank - 1)
        ft.update(rank, 1)
    print(total)

给定测试用例的验证结果

针对输入:

10
7 6 2 4 1 5 10 3 9 8

代码运行后输出结果为19,与手工统计的逆序对总数完全一致。

补充说明:离散化步骤的作用是压缩元素的取值范围,避免数组元素值过大导致树状数组申请不必要的内存,同时对重复元素的统计逻辑完全兼容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 09:24:03