题目:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
方法一:
对于数组中的每个元素,统计之后它小的元素的个数,时间复杂度为O(n^2)
方法二:
观察归并排序
再合并的过程中
{10}和{4}合并变成了{4,10}
{4,10}和{3,6}合并变成了{3,4,6,10}
在这个过程中,我们可以统计出逆序对的个数。——解释不清楚,自己看代码理解
public class Solution {
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.InversePairs(new int[] { 7, 6, 5 }));
}
public int InversePairs(int[] array) {
if (null == array || 0 == array.length)
return 0;
int[] sortedArray = new int[array.length];
return mergeSort(sortedArray, array, 0, array.length - 1);
}
public int mergeSort(int[] sortedArray, int[] array, int begin, int end) {
if (begin >= end)
return 0;
int middle = (begin + end) / 2;
int result = 0;
result += mergeSort(sortedArray, array, begin, middle);
result += mergeSort(sortedArray, array, middle + 1, end);
result += merge(sortedArray, array, begin, middle, end);
return result;
}
private int merge(int[] sortedArray, int[] array, int begin, int middle, int end) {
int count = 0;
int i = middle;
int j = end;
int last = end;
// 归并到临时数组sortedArray时,统计逆序对的个数
while (i >= begin && j > middle) {
if (array[i] > array[j]) {
sortedArray[last] = array[i];
// 统计逆序对的个数
count += j - middle;
--i;
} else {
sortedArray[last] = array[j];
--j;
}
--last;
}
while (i >= begin) {
sortedArray[last--] = array[i--];
}
while (j > middle) {
sortedArray[last--] = array[j--];
}
for (int k = begin; k <= end; ++k) {
array[k] = sortedArray[k];
}
return count;
}
}