求一个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; }