package primary_01;
/*
* 逆序数
* 思路:每个数的左边有多少个数比它大,把个数都加起来,就是数组的逆序数
* 方法:
* 运用归并的思想,将数组依次二分,求出逆序数
*归并排序的思路,在两数判断时加入我们需要的操作
* 运用递归的方式
*/
public class Inverse_number {
/*
* main方法进行方法测试
*/
public static void main(String[] args) {
int arr[]= {2,6,9,1,2,8,6,7};
int arr1[]= {6,5,4,3,2,1};
int count=getInverseNumber(arr,0,arr.length-1);
int count1=getInverseNumber(arr1,0,arr1.length-1);
System.out.println(count);
System.out.println(count1);
}
private static int getInverseNumber(int[] arr, int l, int h) {
if(h <= l || arr.length<2) {
return 0;
}
int count = 0,count1=0,count2=0;
int mid=l+((h-l)>>1); // int mid=l+(h-l)/2;
count1 += getInverseNumber(arr,l,mid);
count2 += getInverseNumber(arr,mid+1,h);
count += merge(arr,l,mid,h);
return count1+count2+count;
}
private static int merge(int[] arr, int l, int mid, int h) {
int count = 0;
int help [] =new int [h-l+1];
int p1=l;
int p2=mid+1;
int index;
for(index=0;p1<=mid && p2<=h ; index++) {
if(arr[p1] < arr[p2]) {
help[index] =arr[p1++];
}else if(arr[p1]>arr[p2]) {
help[index]=arr[p2++];
count += mid-p1+1;
}else { //if(arr[p1] == arr[p2])
help[index] = arr[p2++];
count += mid-p1;
}
}
while(p2 <= h) {
help[index++]=arr[p2++];
}
while(p1 <= mid) {
help[index++]=arr[p1++];
}
for(int i=0;i<help.length;i++) {
arr[l++]=help[i];
}
return count;
}
}
运行结果:
10
15
算法复杂度分析:
/**
* 算法复杂度分析
* 时间复杂度:O(n*logn)
* master公式运用
* master公式的使用
* T(N) = a*T(N/b) + O(N^d)
* 1) log(b,a) > d -> 复杂度为O(N^log(b,a))
* 2) log(b,a) = d -> 复杂度为O(N^d * logN)
* 3) log(b,a) < d -> 复杂度为O(N^d)
* 该算法类似归并排序的思想:T(N)=2*T(N/2)+O(N) 复杂度为O(N*logN)
*/