题目
https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=295&tqId=23260&ru=/exam/oj&qru=/ta/format-top101/question-ranking&sourceUrl=%2Fexam%2Foj
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007
数据范围: 对于
50% 的数据, size≤10 ^4
对于 100% 的数据, size≤10 ^5
数组中所有数字的值满足
0≤val≤10 ^9
要求:空间复杂度 O(n),时间复杂度 O(nlogn)
输入描述:
题目保证输入的数组中没有的相同的数字
示例1
输入:
[1,2,3,4,5,6,7,0]
复制
返回值:
7
复制
示例2
输入:
[1,2,3]
复制
返回值:
0
解题核心
归并排序
答案
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型一维数组
* @return int整型
*/
public int InversePairs (int[] nums) {
//逆序对,核心:归并排序
int n = nums.length;
int step = 1;
int[] ans = {0};
while (step < n) {
int l = 0;
while (l < n) {
int m = l + step - 1;
if (m > n - 1) break;
int r = Math.min(n - 1, m + step);
merge(nums, l, m, r, ans);
l = r + 1;
}
if (step > n / 2) break;
step *= 2;
}
// for (int num : nums) {
// System.out.print(num+" ");
// }
//System.out.println(" ans:"+ ans[0]+" \r\n");
return ans[0];
}
public static void merge(int[] arr, int l, int m, int r, int[] ans) {
int[] help = new int[r - l + 1];
int p1 = l, p2 = m + 1;
int i = 0;
while (p1 <= m && p2 <= r) {
if (arr[p1] <= arr[p2]) {
help[i++] = arr[p1++];
} else {
ans[0] += m - p1 + 1;
ans[0] %= 1000000007;
help[i++] = arr[p2++];
}
}
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (int j = 0; j < help.length; j++) {
arr[l + j] = help[j];
}
}
}