题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例1
输入
1,2,3,4,5,6,7,0
输出
7
题目链接:
package com.sunshine.OFFER66_SECOND; import org.junit.Test; public class A35_InversePairs { @Test public void test() { // 2519 int[] arr = new int[]{364, 637, 341, 406, 747, 995, 234, 971, 571, 219, 993, 407, 416, 366, 315, 301, 601, 650, 418, 355, 460, 505, 360, 965, 516, 648, 727, 667, 465, 849, 455, 181, 486, 149, 588, 233, 144, 174, 557, 67, 746, 550, 474, 162, 268, 142, 463, 221, 882, 576, 604, 739, 288, 569, 256, 936, 275, 401, 497, 82, 935, 983, 583, 523, 697, 478, 147, 795, 380, 973, 958, 115, 773, 870, 259, 655, 446, 863, 735, 784, 3, 671, 433, 630, 425, 930, 64, 266, 235, 187, 284, 665, 874, 80, 45, 848, 38, 811, 267, 575}; InversePairs(arr); System.out.println(ans); } public int InversePairs(int[] array) { mergeSort(array, 0, array.length - 1); return ans; } int ans = 0; public void mergeSort(int[] arr, int left, int right) { if (left == right) { return; } int mid = (left + right) / 2; mergeSort(arr, left, mid); mergeSort(arr, mid + 1, right); //插入排序,慢 // for (int i = mid + 1; i <= right; i++) { // int tmp = arr[i]; // int j = i - 1; // for (; j >= left; j--) { // if (tmp < arr[j]) { // arr[j + 1] = arr[j]; // ans++; // ans %= 1000000007; // } else { // break; // } // } // arr[j + 1] = tmp; // } int i = right; int j = mid; int[] tmp = new int[right - left + 1]; int pos = tmp.length - 1; while (i > mid && j >= left) { if (arr[i] >= arr[j]) { tmp[pos--] = arr[i--]; ans += mid - j; ans %= 1000000007; } else { tmp[pos--] = arr[j--]; } } if (i > mid) { ans += (mid - left + 1) * (i - mid); ans %= 1000000007; while (i > mid) { tmp[pos--] = arr[i--]; } } while (j >= left) { tmp[pos--] = arr[j--]; } for (int k = left; k <= right; k++) { arr[k] = tmp[++pos]; } } }