51. 数组中的逆序对

NowCoder

题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

解题思路

  1. private long cnt = 0;
  2. private int[] tmp; // 在这里声明辅助数组,而不是在 merge() 递归函数中声明
  3. public int InversePairs(int[] nums) {
  4. tmp = new int[nums.length];
  5. mergeSort(nums, 0, nums.length - 1);
  6. return (int) (cnt % 1000000007);
  7. }
  8. private void mergeSort(int[] nums, int l, int h) {
  9. if (h - l < 1)
  10. return;
  11. int m = l + (h - l) / 2;
  12. mergeSort(nums, l, m);
  13. mergeSort(nums, m + 1, h);
  14. merge(nums, l, m, h);
  15. }
  16. private void merge(int[] nums, int l, int m, int h) {
  17. int i = l, j = m + 1, k = l;
  18. while (i <= m || j <= h) {
  19. if (i > m)
  20. tmp[k] = nums[j++];
  21. else if (j > h)
  22. tmp[k] = nums[i++];
  23. else if (nums[i] <= nums[j])
  24. tmp[k] = nums[i++];
  25. else {
  26. tmp[k] = nums[j++];
  27. this.cnt += m - i + 1; // nums[i] > nums[j],说明 nums[i...mid] 都大于 nums[j]
  28. }
  29. k++;
  30. }
  31. for (k = l; k <= h; k++)
  32. nums[k] = tmp[k];
  33. }

51. 数组中的逆序对 - 图1