求一个N个元素的逆序数
例如:{1,5,2,6,3}的逆序数为:0+2+0+1+0=3
最直接的求解逆序数方法时间复杂度为O(N^2)
如果用分治的策略可以将时间复杂度降为O(N*logN),求N个元素的逆序数的分治思想如下:首先求前N/2个元素的逆序数,再求后N/2个
元素的逆序数,最后在排序过程中合并前后两部分之间的逆序数
实现代码如下:
#include<iostream>
using namespace std;
int invalid_input=false;
int cal_reverse(int *data,int len,int start,int end);
int merge_reverse(int *data,int len,int start,int mid,int end);
int main()
{
int n;
cin>>n;
int *data=new int[n];
int i;
for(i=0;i<n;i++)
cin>>data[i];
int num=cal_reverse(data,n,0,n-1);
if(!invalid_input)
cout<<num<<endl;
else
cout<<"invalid input!"<<endl;
delete []data;
return 0;
}
int cal_reverse(int *data,int len,int start,int end)
{
if(data==NULL||len<=0||start>end)
{
invalid_input=true;
return 0;
}
if(start==end)
return 0;
else
{
int mid=(start+end)>>1;
int leftnum=cal_reverse(data,len,start,mid);
int rightnum=cal_reverse(data,len,mid+1,end);
int mergenum=merge_reverse(data,len,start,mid,end);
return leftnum+rightnum+mergenum;
}
}
int merge_reverse(int *data,int len,int start,int mid,int end)
{
int *temp=new int[len];
int i=start,j=mid+1,k=start,count=0;
while(i<=mid&&j<=end)
{
if(data[i]>data[j])
{
count=count+mid-i+1;
temp[k++]=data[j];
j++;
}
else
{
temp[k++]=data[i];
i++;
}
}
while(i<=mid)
{
temp[k++]=data[i];
i++;
}
while(j<=end)
{
temp[k++]=data[j];
j++;
}
for(i=start;i<=end;i++)
data[i]=temp[i];
delete []temp;
return count;
}