35、数组中的逆排序 很好的题目,建议再刷

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

输入描述:

题目保证输入的数组中没有的相同的数字数据范围:    对于%50的数据,size<=10^4    对于%75的数据,size<=10^5    对于%100的数据,size<=2*10^5

示例1

输入

1,2,3,4,5,6,7,0

输出

7
1、只通过50%的笨方法
    int InversePairs(vector<int> data) {
    if (data.size() <= 1) return 0;
    int len = data.size();
    vector<int> dp(len, 0);
    for (int i = len - 2; i >= 0; --i) {

        for (int j = i + 1; j < len; ++j) {
            if (data[i] > data[j]) { 
                //dp[i] = max(dp[i], dp[j] + 1); 
                dp[i]++;
            }

        }
    }

    return  accumulate(dp.begin(), dp.end(), 0) % 1000000007;

    }
2、牛客上的一种做法,很厉害

https://www.nowcoder.com/profile/872855282/codeBookDetail?submissionId=78340272

int InversePairs(vector<int> data) {
    if (data.size() == 0)
        return 0;
    vector<int> copy(data);    // 辅助数组,每次递归后有序
    return InversePairsCore(data, copy, 0, data.size() - 1);
}

int InversePairsCore(vector<int>& data, vector<int>& copy, int begin, int end) {
    if (begin == end)
        return 0;
    int mid = begin + (end - begin) /2;
    int left = InversePairsCore(copy, data, begin, mid);//这里的一步很绝啊,减少了交换的这一步
    int right = InversePairsCore(copy, data, mid + 1, end);

    int end1 = mid;     // 比较从尾端开始
    int end2 = end;    // 比较从尾端开始
    int index_copy = end;       // 比较结果存入辅助数组尾端
    long res = 0;

    // 归并排序:相当于两个有序数组合成一个有序表(从尾端开始是为了计数)
    while (begin<= end1 && mid + 1<= end2) {
        if (data[end1] > data[end2]) {
            copy[index_copy--] = data[end1--];
            res += end2 - mid;
            res %= 1000000007;
        }
        else
            copy[index_copy--] = data[end2--];
    }

    while (begin<= end1)
        copy[index_copy--] = data[end1--];
    while (mid + 1<= end2)
        copy[index_copy--] = data[end2--];

    return (left + right + res) % 1000000007;
}

InversePairsCore(copy, data, begin, mid)中 copy和data互换位置好评。。。这样就减少了赋值的那一步了。。。。。

二刷:
1、很棒的一道题目,建议多刷
int InversePairsCore(vector<int>& data, vector<int>& copy, int begin, int end) {
    if (begin == end)
        return 0;
    int mid = begin + (end - begin) / 2;
    int low1 = begin, high1 = mid, low2 = mid + 1, high2 = end;
    int left = InversePairsCore(copy, data, low1, high1);//这里的一步很绝啊,减少了交换的这一步
    int right = InversePairsCore(copy, data, low2, high2);

    long res = 0;
    int copyIndex = low1;
    // 归并排序:相当于两个有序数组合成一个有序表
    while (low1 <= high1 && low2 <= high2) {
        if (data[low1] > data[low2]) {
            copy[copyIndex++] = data[low1++];
            res += high2 - low2 + 1;// data[low1] > data[low2],那么这一次