493. 翻转对
给定一个数组
nums,如果i < j且nums[i] > 2*nums[j]我们就将(i, j)称作一个重要翻转对。 你需要返回给定数组中的重要翻转对的数量。 示例 1: 输入: [1,3,2,3,1] 输出: 2示例 2: 输入: [2,4,3,5,1] 输出: 3
注意:
- 给定数组的长度不会超过
50000。- 输入数组中的所有数字都在32位整数的表示范围内。
解题思路
归并排序
class Solution {public:int reversePairs(vector<int>& nums) {return mergeAndCnt(nums,0,nums.size() - 1);}int mergeAndCnt(vector<int>& nums,int left,int right) {if( left >= right)return 0;int mid = left + ((right - left) >> 1);int cnt = mergeAndCnt(nums,left,mid) + mergeAndCnt(nums,mid+1,right);int j = mid + 1;for(int i=left;i <= mid;i++) {while( j <= right && nums[i] > nums[j]*2LL)j++;cnt += j - (mid + 1);}merge(nums,left,mid,right);return cnt;}void merge(vector<int>& nums,int left,int mid,int right) {int n1 = mid - left + 1;int n2 = right - mid;int leftNums[n1],rightNums[n2];for(int i=0;i< n1;i++)leftNums[i] = nums[left + i];for(int i=0;i< n2;i++)rightNums[i] = nums[mid + 1 + i];int i = 0,j = 0;for(int k = left;k <= right;k++) {if(j >= n2 || (i < n1 && leftNums[i] <= rightNums[j]))nums[k] = leftNums[i++];elsenums[k] = rightNums[j++];}}};
