import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param nums int整型一维数组 * @return int整型 */ public int InversePairs (int[] nums) { // write code here // 左程云老师讲过,通过归并排序过程中的左右两个字串的比较,可以实现逆序对的统计 // 算法的时间复杂度O(NlogN),空间复杂度O(N) // 调用归并排序的递归执行方法 int count = process(nums, 0, (nums.length - 1)); // 注意题目要求,对1000000007取模 return count % 1000000007; } // 递归执行方法 public int process(int[] nums, int l, int r) { // 递归出口 if (l == r) { return 0; } // 计算中间索引 int mid = (l + r) / 2; // 返回递归过程产生的逆序对数量 int count = process(nums, l, mid) + process(nums, mid + 1, r) + compareAndMerge(nums, l, mid, r); // 注意题目要求,对1000000007取模 return count % 1000000007; } // 比较与归并方法 public int compareAndMerge(int[] nums, int l, int mid, int r) { // 记录逆序对的个数 int count = 0; // 比较,归并 int[] tempNums = new int[r - l + 1]; // nums的左半区下标 int leftIndex = l; // nums的右半区下标 int rightIndex = mid + 1; // tempNums的下标 int tempIndex = 0; while (leftIndex <= mid && rightIndex <= r) { // 请注意,归并排序merge的一个前提是,左右两个半区各自有序 if (nums[leftIndex] < nums[rightIndex]) { // 左边 < 右边,则左边先进入tempNums中,leftIndex和tempIndex都++ tempNums[tempIndex] = nums[leftIndex]; leftIndex++; } else { // 左边 > 右边,则右边先进入tempNums中,rightIndex和tempIndex都++ // 注意!此时算作逆序对! tempNums[tempIndex] = nums[rightIndex]; rightIndex++; // tempNums[leftIndex]大,说明从leftIndex到mid上的数都更大,逆序数要全算上 count += (mid - leftIndex + 1); // 注意题目要求,对1000000007取模 count %= 1000000007; } tempIndex++; } // 此时退出了循环,要么leftIndex越界,要么rightIndex越界,以下两个while最多执行一个 while (leftIndex <= mid) { // 右边的rightIndex先越界了,说明左边剩下的元素都比右边的大,把左边剩下的元素全部送进tempNums中 // 注意!这里的逆序对已经被上一个while中考虑到了 tempNums[tempIndex] = nums[leftIndex]; leftIndex++; tempIndex++; } while (rightIndex <= r) { // 左边的leftIndex先越界了,说明右边剩下的元素都比左边的大,把右边剩下的元素全部送进tempNums中 tempNums[tempIndex] = nums[rightIndex]; rightIndex++; tempIndex++; } // 最后,把tempNums排好序的内容写回nums的对应位置 for (int i = 0; i < tempNums.length; i++) { nums[l + i] = tempNums[i]; } // 返回统计到的逆序数 return count; } }