我需要一个算法来计算类型的反转: 如果a具有较低的索引并且a> b,则存在a和b之间的反转。 2b中。
你能想到一个能在O(n logn)中做到的算法吗?
答案 0 :(得分:2)
可以通过合并排序算法中的小调整来完成。 Counting inversions in an array
在合并阶段的常规标准算法中,您比较左半部分和右半部分的元素,并按左部分中剩余的元素数量增加反转。这里我们不是通过左半部分剩余的元素数量来增加,而是通过左半部分剩余的元素数量增加两倍以上。
答案 1 :(得分:0)
A[1..n]
B[1..n] = copy(A)
sort(B) //n*log(n)
for i = 1 to n-1
//log(n)
exists = specialBinarySearch(B, A[i], 1, n)
//log(n)
setHighest(B, A[i], 1, n)
if exists
count++
specialBinarySearch(a, key, from, to)
if from <= to
mid = from + (to-from)/2
if a[mid] < floor(key/2)
return true
else //must go to left of it to get even smaller value
specialBinarySearch(a, key, from, mid-1)
else
return false
setHighest(a, key, from, to)
if from <= to
mid = from + (to-from)/2
if a[mid] == key
a[mid] = INT_MAX
else if a[mid] < key
setHighest(a, key, mid+1, to)
else
setHighest(a, key, from, mid-1)
行。所以,基本上就是这些步骤。
a
,在B中对任何元素B[i]
执行二进制搜索,使a > 2*B[i]
。为O(log 名词)。 (我编写的算法是为了避免溢出)B[i]
,因此请设置B[i] = infinity
使其无法进行比较。另一个二分搜索。为O(log 名词)所以,我们计算一下
O(n) + O(n*log(n)) + n*O(log(n))
=> O(n*log(n)) asymptotically
答案 2 :(得分:0)
这可以使用动态订单统计数据结构来解决。我知道这种结构有两种选择:
按顺序对数组的每个元素(b
),在订单统计数据结构中查找值2b
的等级。然后将b
插入到订单统计数据结构中。
值2b
的等级给出了元素a
的数量,它们具有较低的索引且小于2b
。这些数字的总和给出了“反转”的数量。