【剑指offer】面试题51:数组中的逆序对【C++版本】

总结的部分题目思路与代码,待完善。
【剑指offer-第二版】部分题目与解答【C++版本】

题目:

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如在数组{7,5,6,4}中,一共存在5个逆序对。

解题思路:

1.强解的复杂度太高了。
2.使用二分的思路来求解。具体解题思路见书

可以AC的解法【C++版本】

#include <iostream>
#include <vector>

using namespace std;

int InversePairs(vector<int> data);
int InversePairsCore(vector<int> &data, vector<int> &tmp, int start, int end);

int main()
{
    //测试用例
    vector<int> data{ 1,2,3,4,5,6,7,0 };

    cout << InversePairs(data) << endl;

    system("pause");
    return 0;
}

int InversePairs(vector<int> data) {
    int size = data.size();
    if (size <= 1)return 0;

    vector<int> tmp = data;

    int resu = InversePairsCore(data, tmp, 0, size - 1);

    return resu;
}

int InversePairsCore(vector<int> &data, vector<int> &tmp, int start, int end) {
    if (start == end) {
        tmp[start] = data[start];
        return 0;
    }

    int length = (start + end) / 2;
    //这里递归很不好理解,每次返回data都是有序的(调用内部对data,即函数内部的tmp排序)
    //出来过后data有序了,又使用data对tmp排序,这样外部的data又是有序的了
    int low = InversePairsCore(tmp, data, start, length);
    int high = InversePairsCore(tmp, data, length + 1, end);

    int i = length, j = end, index = end;
    long long cnt = 0;      //牛客网的题最后结果比较大,用long long来存
    while (i >= start && j >= (length + 1)) {
        if (data[i] > data[j]) {
            tmp[index--] = data[i--];
            cnt += j - length;
        }
        else {
            tmp[index--] = data[j--];
        }
    }

    for (; i >= start; i--) {
        tmp[index--] = data[i];
    }
    for (; j >= (length + 1); j--) {
        tmp[index--] = data[j];
    }

    return static_cast<int>((low + high + cnt) % 1000000007);   //需要求模
}

猜你喜欢

转载自blog.csdn.net/m0_37950361/article/details/81988385