Leetcode 493. 翻转对 C++

Leetcode 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
注意:
  1. 给定数组的长度不会超过50000。
  2. 输入数组中的所有数字都在32位整数的表示范围内。

题解

这道题和求逆序对的思想其实是一致的,因此我们采用归并排序的方法进行求取翻转对,详细过程见代码

代码

	int mergeSort(vector<int>& nums,int l,int r){		//排序l~r,同时求取翻转对
        if(l >= r)  return 0;
        int res = 0,mid=(l+r)/2;
        res += mergeSort(nums,l,mid);		//保证l~mid有序,且返回这部分的翻转对
        res += mergeSort(nums,mid+1,r);		//保证mid+1~r有序,且返回这部分的翻转对
        int tl=l,tm=mid,tr=mid+1;			//求取l~r的翻转对
        while(tl<=mid && tr<=r){			
            if ((long)nums[tl] > 2 * (long)nums[tr]) {		//因为l~mid、mid+1~r是有序的,因此当nums[tl] > 2*nums[tr]的时候,说明tl~mid的数都可以和tr构成翻转对
                res += mid - tl + 1;
                ++tr;
            } else {
                ++tl;
            }
        }
        vector<int> tmp(r-l+1);		
        int i=l,j=mid+1,k=0;	//两个有序集合进行合并
        while(i<=mid && j<=r){
            if(nums[i]<=nums[j]){
                tmp[k++] = nums[i++];
            }else   tmp[k++] = nums[j++];
        }
        while(i<=mid)   tmp[k++] = nums[i++];
        while(j<=r) tmp[k++] = nums[j++];
        for(int i=l; i<=r; i++){
            nums[i] = tmp[i-l];
        }
        return res;
    }
    int reversePairs(vector<int>& nums) {
        return mergeSort(nums,0,nums.size()-1);
    }

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

你可能感兴趣的:(Leetcode 493. 翻转对 C++)