序列逆序数:
由1,2,…,n 组成的一个有序数组称为一个n级排列。在一个排列中如果一对数的前后位置与大小顺序相反,即大数排在小数的前面,则称它们为一个逆序。一个排列中所有逆序的总和称为该排列的逆序数。
那么,如何求解一个序列的逆序数呢?暴力法是问题解的最简单的方法,下面给出核心代码:
int InversionNumber(int num[], int N){ int count = 0; for (int i = N - 1; i > 0; i--) { for(int j = 0; j < i; j++) { if(num[j] > num[i]) count++; } } return count; }直接根据定义暴力求解固然简单,但是往往效率不高,O(n^2)的复杂度在数据规模较大的时候,是不很乐观的。
归并求逆序简单原理:
归并排序是分治的思想,具体原理自己去看书吧。利用归并求逆序是指在对子序列 s1和s2在归并时,若s1[i]>s2[j](逆序状况),则逆序数加上s1.length-i,因为s1中i后面的数字对于s2[j]都是逆序的。下面为核心代码
void merge(int l,int mid,int r,int arr[]) { int i=l,j=mid+1; int k=0; while(i<=mid&&j<=r) { if(arr[i]<arr[j]) t[++k]=arr[i++]; else t[++k]=arr[j++]; } while(i<=mid) t[++k]=arr[i++]; while(j<=r) t[++k]=arr[j++]; for(int p=1;p<=k;p++) arr[p+l-1]=t[p]; } void mergesort(int l,int r,int arr[]) { if(l<r) { int mid=(l+r)>>1; mergesort(l,mid,arr); mergesort(mid+1,r,arr); merge(l,mid,r,arr); } }