我在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)
复杂性),我要感谢有关上述解决方案的一些参考。
答案 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位),它是线性的。