这种用于计算数组O(n)中的反转的算法是否复杂?

时间:2015-07-19 11:32:59

标签: algorithm

我在Python找到了问题Count inversions in the array的解决方案,它使用"非比较排序算法来获取计数"。它对代码执行2次递归调用,执行按位运算。

def inv_count(a, m=(1 << 32)):
    if not m or not a:
        return 0
    count = 0
    ones, zeros = [], []
    for n in a:
        if n & m:
            ones.append(n & ~m)
        else:
            count += len(ones)
            zeros.append(n & ~m)
    m /= 2
    return count + inv_count(ones, m) + inv_count(zeros, m)


print inv_count([1, 2, 3, 4, 5])
print inv_count([2, 4, 1, 3, 5])
print inv_count([5, 4, 3, 2, 1])

此解决方案是否真正线性O(n)

类似的SO问题声称它不可能(Is there an algorithm to count array inversions in linear time?),虽然有很多关于分而治之算法的文献(O(n logn)复杂性),我要感谢有关上述解决方案的一些参考。

2 个答案:

答案 0 :(得分:3)

它是O(n w),其中最大数小于2 ^ w。如果w = 32,正如代码所假设的那样,则是,这是线性时间算法。另一方面,存在基于O(n log d)时间比较的算法,用于具有至多d个不同元素的输入,当d = 2 ^ w = 2 ^ 32时,该算法也是线性的。 Ω(n log n) - 时间下限适用于基于比较的算法,其中所有输入元素可能是不同的。

答案 1 :(得分:1)

是的,对于受数值限制的数字(32位),它是线性的。

与排序计数(https://en.wikipedia.org/wiki/Counting_sort)类似。