Finding the number of inversions

Recall the problem of finding the number of inversions. As in the course, we are given a sequence of n numbers a 1 ,··· ,a n , which we assume are all distinct, and we difine an inversion to be a pair i < j such that a i > a j .

We motivated the problem of counting inversions as a good measure of how different two orderings are. However, one might feel that this measure is too sensitive. Let’s call a pair a significant inversion if i < j and a i > 3a j . Given an O(nlogn) algorithm to count the number of significant inversions between two orderings.

类似于求逆序数的个数,不断地将序列A分割为2个子序列,在递归调用时计算各一半的逆序数,在进行合并时再分别计算位于左边和右边的逆序数。递归对序列进行分割时,序列中剩一个数时就无法再分了。在合并的函数中,比较左边L[i]和右边子数组的R[j],如果L[i] > 3R[j],那么L[i]后面的数都比 3R[j]要大,不需要再比较了,因此逆序数的个数增加了子数组L的长度减i个。

当在单个子数组内求逆序对的个数时,显然是没有问题的。

当在两个子数组之间合并并求逆序对的个数时,假设两个子数组分别为A[]和B[],则两个数组的长度分别为Length(A)和Length(B),并且这两个子数组都已经是有序的(从小大排列),当A[i] > B[j]时,数组A[i]至A[Length(a)]这些值都是大于B[j]的。

MergeAndCount()函数中,需要循环执行的是两个for循环,因此该函数的时间复杂度为O(n)。根据二分算法,序列A最多能被分割log 2 n次,也就是MergeAndCount()函数最多可以执行 log 2 n次。因此时间复杂度为O(nlog 2 n)。

伪代码如下:


这里写图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值