逆序对
设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同。
如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对,也称作逆序数。
解法一:
说明:穷举,两层for循环依次比对。
输入:数组A[]
输出:逆序对数目
Java代码:
public static int countInversion(int[] a){
int n=a.length;
int count=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]>a[j])count++;
}
}
return count;
}
解法二:
分治法
输入:数组A[]
输出:逆序对数目
Java代码:
static int[] a;
static int[] b;
static int count=0;
public static int countInversion(int[] a){
int n=a.length;
int count=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]>a[j])
count++;
}
}
return count;
}
public static void merger(int begin,int end){
int mid=(begin+end)/2;
int p=begin,q=mid+1;
int k=begin;
while(p<=mid&&q<=end){
if(a[p]<=a[q]){
b[k++]=a[p++];
}else{
b[k++]=a[q++];
count+=mid-p+1;
//System.out.println(begin+" "+end+":"+(mid-p+1));
}
}
while(p<=mid)b[k++]=a[p++];
while(q<=end)b[k++]=a[q++];
//copy
for(int i=begin;i<=end;i++){
a[i]=b[i];
}
}
public static void mergerInversion(int begin,int end){
if(begin<end){
int mid=(begin+end)/2;
mergerInversion(begin,mid);
mergerInversion(mid+1,end);
merger(begin,end);
}
}