/*
* 面试题51:数组中的逆序对
* 题目:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
* 输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
* 思路:过程:先把数组分割成子数组,先统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目。
* 在统计逆序对的过程中,还需要对数组进行排序。如果对排序算法很熟悉,我们不难发现这个过程实际上就是归并排序。
* 归并排序的改进,把数据分成前后两个数组(递归到分成很多个数组,每个数组仅有一个数据项),再合并数组,
* 合并时,出现前面的数组值array[start]大于后面数组值array[end]时;
* 则前面数组array[start]~array[mid]都是大于array[end]的,count += mid+1 - start。
*/
public class No51InversePairs {
public static void main(String[] args) {
No51InversePairs n = new No51InversePairs();
int[] arr = {7, 5, 6, 4};
System.out.println(n.InversePairs(arr));
}
int count = 0;
public int InversePairs(int[] array) {
if (array == null || array.length == 0) {
return 0;
}
mergeSort(array, 0 ,array.length - 1);
return count;
}
private void mergeSort(int[] data, int start, int end) {
int mid = (start + end) / 2;
if (start < end) {
mergeSort(data, start, mid);
mergeSort(data,mid + 1, end);
merge(data, start, mid, end);
}
}
private void merge(int[] data, int start, int mid, int end) {
int arr[] = new int[end - start + 1];
int c = 0;
int s = start;
int index = mid + 1;
while (start <= mid && index <= end) {
if (data[start] < data[index]) {
arr[c++] = data[start++];
} else {
arr[c++] = data[index++];
count += mid - start + 1;
count %= 1000000007;
}
}
while (start <= mid) {
arr[c++] = data[start++];
}
while (index <= end) {
arr[c++] = data[index++];
}
for (int d : arr) {
data[s++] = d;
}
}
}
面试题51:数组中的逆序对
最新推荐文章于 2021-05-09 15:12:23 发布