数组中的逆序对

来源:互联网 发布:淘宝花呗卖家开通条件 编辑:程序博客网 时间:2024/05/29 19:22

题目

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

思路

每一次把当前要统计的范围分成前半部和后半部分,递归统计前半部分和后半部分各自里面的逆序对数目,剩下的就是统计前半部分和后半部分之间的逆序对数目了,这个时候利用归并排序的思想,对于前半部分和后半部分,在之前的递归中分别已经排序好,然后和前半部分和后半部分归并起来,按照从大到小的顺序归并,注意:
1. 当前半部分要归并的元素比后半部分要归并的元素大时,那么从后半部分的头到当前元素开始的元素都是比这个元素小的,这个长度就是和这个元素组成的逆序对的数目,并把前半部分的指针往前;
2. 当前半部分要归并的元素比后半部分要归并的元素小时,把后半部分的要归并的元素归并起来,并把后半部分的指针往前;
最终的结果加起来就是所有的逆序对的数目。

参考代码

class Solution {public:    int InversePairs(vector<int> data) {        if (data.size() <= 1) return 0;        else {            vector<int> tmp(data);            return calculate(data, tmp, 0, data.size() - 1) % 1000000007;        }    }private:    long long calculate(vector<int>& data, vector<int>& tmp, int st, int ed) {        if (st == ed) return 0;        long long length = (ed - st) / 2;        long long left = calculate(tmp, data, st, st + length);        long long right = calculate(tmp, data, st + length + 1, ed);        long long cnt = 0;        long long i = st + length, j = ed, temp = ed;        while (i >= st && j >= st + length + 1) {            if (data[i] > data[j]) {                cnt += j - st - length;                tmp[temp--] = data[i--];            } else {                tmp[temp--] = data[j--];            }        }        while (i >= st) {            tmp[temp--] = data[i--];        }        while (j >= st + length + 1) {            tmp[temp--] = data[j--];        }        return (left + right + cnt) % 1000000007;    }};
原创粉丝点击