关于3倍数的逆序数,即当i<j时,a[i]>3a[j]的序列逆序数。

来源:互联网 发布:阿里云平台介绍 编辑:程序博客网 时间:2024/06/05 00:41

题目描述:

        Recall the problem of finding the number of inversions. As in the course, we are given a
sequence of n numbers a 1,· · · , an, which we assume are all distinct, and we difine an inversion
to be a pair i < j such that a i > aj
    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 inversionif i < j and a i >3aj. Given anO(nlog n) algorithm to count the
number of significant inversions between two orderings.

解题思路:
  

    根据本题的叙述,我们可以按照一般求逆序数的思路来解决这个问题。除了在计算逆序数加一的时候加入a[i]>3a[j]进行判断即可。根据定义,

我们这样定义一个序列的逆序数:序列a[1]a[2]a[3]a[4]...a[n]。这个序列的逆序数C,等于a[1]a[2]a[3]a[4]...的逆序数的和。

C=sum(Ci),其中我们定义Ci为满足a[i]>3*a[j](i<j)的数的总的个数,即Ci=sum(a[i]>3*a[j]),(i<j)。

下面,我们采用递归分治的算法进行伪代码说明解释:

        

   INVERSION(a_array,start_position,end_position)

   {

     n=a_array.length;

     If n==1

     return 0;

     else

     {

       mid_position=(start_position+end_position)/2;

N1=INVERSION(a_array,start_position,mid_position);

N2=INVERSION(a_array,mid_position+1,end_position);

N3=Merger(a_array,start_position,end_position);

     }

return N=N1+N2+N3;

   }

Merge (a_array,start_position,end_position)

{

得到数组a_array分开后的左右数组L_array,R_array;

i=0;j=0;

InversionCount=0;

for(k=0 to end)

{

if (L_array[i]>R_array[j])

{

A[k]=L_array[i];

i++;

}

if(L_array[i]>3*R_array[j])

InversionCount=InversionCount+j-k;

else 

{

A[k]=R[j];

j++;

}

}

}

时间复杂性分析:

因为在这里,T(n)<2T(n/2)+cn,其中Merge的时间复杂度为cn,每一次的递归,规模减半,因此最终的时间复杂度为o(n log n).

0 0
原创粉丝点击