在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
第一种方法:暴力遍历
public class Solution {
public static void main(String[] args) {
//第一种方法:暴力遍历,复杂度 O(n^2)
int[] array = {1,2,3,4,5,6,7,0};
Solution s = new Solution();
System.out.println(s.InversePairs(array));
}
public int InversePairs(int [] array) {
int num = 0;
for(int i=0;i<array.length;i++){
for(int j=i+1;j<array.length;j++){
if(array[i]>array[j]){
num+=1;
}
}
}
int x = num%1000000007;
return x;
}
}
第二种方法:归并实现
public class Solution {
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7,0};
Solution s = new Solution();
System.out.println(s.InversePairs(array));
}
public int InversePairs(int[] array) {
if (array == null || array.length <= 0) {
return 0;
}
int pairsNum = mergeSort(array, 0, array.length - 1);
return pairsNum;
}
public int mergeSort(int[] array, int left, int right) {
if (left == right) {
return 0;
}
int mid = (left + right) / 2;
int leftNum = mergeSort(array, left, mid);
int rightNum = mergeSort(array, mid + 1, right);
return (Sort(array, left, mid, right) + leftNum + rightNum) % 1000000007;
}
public int Sort(int[] array, int left, int middle, int right) {
int current1 = middle;
int current2 = right;
int current3 = right - left;
int temp[] = new int[right - left + 1];
int pairsnum = 0;
while (current1 >= left && current2 >= middle + 1) {
if (array[current1] > array[current2]) {
temp[current3--] = array[current1--];
pairsnum += (current2 - middle); // 这个地方是current2-middle!!!!
if (pairsnum > 1000000007)// 数值过大求余
{
pairsnum %= 1000000007;
}
} else {
temp[current3--] = array[current2--];
}
}
while (current1 >= left) {
temp[current3--] = array[current1--];
}
while (current2 >= middle + 1) {
temp[current3--] = array[current2--];
}
// 将临时数组赋值给原数组
int i = 0;
while (left <= right) {
array[left++] = temp[i++];
}
return pairsnum;
}
}
本文介绍两种计算数组中逆序对总数的方法:暴力遍历和归并排序。暴力遍历简单但效率低,时间复杂度为O(n^2)。归并排序则通过分治策略提高效率,同时计算逆序对数量,最终返回结果模1000000007。
237

被折叠的 条评论
为什么被折叠?



