剑指 Offer 51. 数组中的逆序对

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

 

示例 1:

输入: [7,5,6,4]
输出: 5

 

限制:

0 <= 数组长度 <= 50000

解析:

  当然可以树状数组,但归并代码更容易记住

  每次归并时,如果取的是右半边的,说明左半边的[p, m]区间的数是大于A[q]这个数的

  因此ret += (m - p + 1)

  

class Solution {
public:
    void merge(vector<int> &nums, int l, int r, int& ret)
    {
        if(l >= r) return;
        int m = (l + r) / 2;
        merge(nums, l, m, ret);
        merge(nums, m + 1, r, ret);
        int p = l, q = m + 1;
        vector<int> C;
        while(p <= m || q <= r)
        {

            if(p > m || (q <= r && nums[p] > nums[q]))
            {

                C.push_back(nums[q]), q++, ret += (m - p + 1);
                
            }
            else
                C.push_back(nums[p]), p++;
        }

        for(int i = 0; i < C.size(); i++)
        {
            nums[l + i] = C[i];
        }
        
    }

    int reversePairs(vector<int>& nums) {
        int ret = 0;
        int n = nums.size() - 1;
        merge(nums, 0, n, ret);

        return ret;

    }
};

 

posted @ 2022-04-15 15:25  WTSRUVF  阅读(13)  评论(0编辑  收藏  举报