题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
思路1:
暴力穷举法
思路2:
分治的思想:先求前面一半数组的逆序数,再求后面一半数组的逆序数,然后求前面一半数组比后面一半数组中大的数的个数(也就是逆序数),这三个过程加起来就是整体的逆序数目了。其实也就是归并排序
import java.util.Scanner;
public class InversePairs {
static int count = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
System.out.println("the size of array:");
int n = scanner.nextInt();
int[] array = new int[n];
System.out.println("input the array:");
for(int i=0;i<n;i++){
array[i] = scanner.nextInt();
}
System.out.println("results:" + InversePairs1(array));
}
//方法1:暴力穷举法
public static int InversePairs(int[] array) {
int len = array.length;
if(len == 0 || len == 1){
return 0;
}
int count = 0;
for(int i=0;i<len-1;i++){
for(int j=i+1;j<len;j++){
if(array[i] > array[j]){
count++;
}
}
}
return count;
}
//方法2:归并排序
public static int InversePairs1(int[] array) {
int len = array.length;
int[] temp = new int[len];
return twoMergeSort(array, 0, len - 1, temp);
}
//合并两个有序数组
public static int mergeOrderdArrays(int a[], int first, int mid, int last, int[] temp){
int i = first;
int j = mid + 1;
int m = mid,n = last;
int k = 0;
while(i <= m && j <= n){
if(a[i] > a[j]){
temp[k++] = a[j++];
count += mid - i + 1; // 右侧的数都大于a[j]
}
else{
temp[k++] = a[i++];
}
}
while(i <= m){
temp[k++] = a[i++];
}
while(j <= n){
temp[k++] = a[j++];
}
for(i=0;i<k;i++){
a[first + i] = temp[i];
}
return count;
}
public static int twoMergeSort(int a[], int first, int last, int[] temp){
if(first < last){
int mid = (first + last)/2;
twoMergeSort(a, first, mid, temp);//左边有序
twoMergeSort(a, mid + 1, last, temp); //右边有序
count = mergeOrderdArrays(a, first, mid, last, temp);//合并两个有序的数组
}
return count;
}
}