493. 翻转对

给定一个数组 nums ,如果 i < jnums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。 你需要返回给定数组中的重要翻转对的数量。 示例 1: 输入: [1,3,2,3,1] 输出: 2

示例 2: 输入: [2,4,3,5,1] 输出: 3

注意:

  1. 给定数组的长度不会超过50000
  2. 输入数组中的所有数字都在32位整数的表示范围内。

解题思路

归并排序

  1. class Solution {
  2. public:
  3. int reversePairs(vector<int>& nums) {
  4. return mergeAndCnt(nums,0,nums.size() - 1);
  5. }
  6. int mergeAndCnt(vector<int>& nums,int left,int right) {
  7. if( left >= right)
  8. return 0;
  9. int mid = left + ((right - left) >> 1);
  10. int cnt = mergeAndCnt(nums,left,mid) + mergeAndCnt(nums,mid+1,right);
  11. int j = mid + 1;
  12. for(int i=left;i <= mid;i++) {
  13. while( j <= right && nums[i] > nums[j]*2LL)
  14. j++;
  15. cnt += j - (mid + 1);
  16. }
  17. merge(nums,left,mid,right);
  18. return cnt;
  19. }
  20. void merge(vector<int>& nums,int left,int mid,int right) {
  21. int n1 = mid - left + 1;
  22. int n2 = right - mid;
  23. int leftNums[n1],rightNums[n2];
  24. for(int i=0;i< n1;i++)
  25. leftNums[i] = nums[left + i];
  26. for(int i=0;i< n2;i++)
  27. rightNums[i] = nums[mid + 1 + i];
  28. int i = 0,j = 0;
  29. for(int k = left;k <= right;k++) {
  30. if(j >= n2 || (i < n1 && leftNums[i] <= rightNums[j]))
  31. nums[k] = leftNums[i++];
  32. else
  33. nums[k] = rightNums[j++];
  34. }
  35. }
  36. };