【在线编程】数组中的逆序对
【问题描述】
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
【解题思路 & Java实现】
必知排序算法:归并排序。
import java.util.Arrays;
/**
* 归并排序(二路归并):基于分治的思想
* 时间复杂度:任何情况下都是 O(nlogn)
* 稳定性:稳定
*/
public class MergeSort {
public static int[] temp; //辅助数组
public static void main(String[] args) {
int[] array = {1, 3, 2, 6, 8, 7, 5};
System.out.println(Arrays.toString(array));
mergeSort(array, 0, array.length - 1);
System.out.println(Arrays.toString(array));
}
public static void mergeSort(int[] array, int left, int right) {
if (left < right) {
temp = new int[array.length];
int middle = (left + right) / 2;
mergeSort(array, left, middle); //对左半边进行归并排序
mergeSort(array, middle + 1, right); //对右半边进行归并排序
merge(array, left, middle, right); //合并左右
}
}
//合并两个有序子序列
public static void merge(int[] array, int left, int middle, int right) {
int i = left; //遍历左子序列
int j = middle + 1; //遍历右子序列
int k = left; //遍历辅助数组
while (i <= middle && j <= right) {
if (array[i] <= array[j]) { //==放在这保证归并排序的稳定性
temp[k++] = array[i++];
} else {
temp[k++] = array[j++];
}
}
while (i <= middle) temp[k++] = array[i++];
while (j <= right) temp[k++] = array[j++];
for (int index = left; index <= right; index++) {
array[index] = temp[index];
}
}
}
思路:在归并排序过程中记录逆序数对。时间复杂度 O(nlogn).
public class Solution {
int count;
int[] temp;
public int InversePairs(int[] array) {
if (array == null || array.length <= 0) {
return 0;
}
count = 0;
temp = new int[array.length];
mergeSort(array, 0, array.length - 1);
return count;
}
public void mergeSort(int[] array, int left, int right) {
if (left < right) {
int middle = (left + right) / 2;
mergeSort(array, left, middle);
mergeSort(array, middle + 1, right);
merge(array, left, middle, right);
}
}
public void merge(int[] array, int left, int middle, int right) {
int i = left;
int j = middle + 1;
int k = left;
while (i <= middle && j <= right) {
if (array[i] <= array[j]) {
temp[k++] = array[i++];
} else {
count += middle - i + 1; //左序列中array[i]以及后面的数字都大于array[j]
if (count >= 1000000007) count = count % 1000000007;
temp[k++] = array[j++];
}
}
while (i <= middle) temp[k++] = array[i++];
while (j <= right) temp[k++] = array[j++];
for (int index = left; index <= right; index++)
array[index] = temp[index];
}
}