493. Reverse Pairs 逆序数 类似剑指offer

来源:互联网 发布:淘宝店铺招牌图片童装 编辑:程序博客网 时间:2024/06/05 16:58

Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].

You need to return the number of important reverse pairs in the given array.

Example1:

Input: [1,3,2,3,1]Output: 2

Example2:

Input: [2,4,3,5,1]Output: 3

Note:

  1. The length of the given array will not exceed 50,000.
  2. All the numbers in the input array are in the range of 32-bit integer.

这个题目改进了原题的要求。

我的思路: 归并排序。不通过。

正确题解:

在递归函数中递归后,先不合并,首先处理逆序数,然后再合并。这样需要再写一个合并函数。这样的好处是在处理计数的时候不需要考虑谁先被写入copy数组。使得复杂度降低。

class Solution {public:    int reversePairs(vector<int>& nums) {        return divide(nums,0,nums.size()-1);    }    int divide(vector<int>& nums,int start,int end){        if(start<end)        {        int mid=start+(end-start)/2;        int count=divide(nums,start,mid)+divide(nums,mid+1,end);        int j=mid+1;        for(int i=start;i<=mid;i++)        {            while(j<=end&&nums[i]>nums[j]*2LL)            {                j++;            }            count+=j-mid-1;        }        merge(nums,start,mid,end);        return count;        }        else            return 0;            }     void merge(vector<int>& A,int start,int mid,int end){        int n1=mid-start+1;        int n2=end-mid;        vector<int> left(A.begin()+start,A.begin()+mid+1);        vector<int> right(A.begin()+mid+1,A.begin()+end+1);        int i=0;        int j=0;        for(int k=start;k<=end;k++)        {            if(j>=n2||(i<n1&&left[i]<=right[j]))//有等号,目的是先把左边的尽量加入进来            {                A[k]=left[i++];            }            else            {                A[k]=right[j++];            }        }    }};