美文网首页
数组中的逆序对-分治(归并排序)

数组中的逆序对-分治(归并排序)

作者: 科研的心 | 来源:发表于2018-09-27 09:43 被阅读37次

    题目描述

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

    输入描述

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


    示例

    输入

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

    输出

    7


    思路

    因为这一题的vector的size很大,以至于直接遍历寻找逆序对会超时,为了避免这种情况,我使用分治中归并算法,在排序的过程中寻找逆序对的数量。
    由归并算法的特点可知,每次归并的两个序列都是内部有序的,所以,当左边的序列中的l[i]>右边序列中的r[j]时,左边序列中其他未遍历的值l[i+1]、l[i+2]...l[mid]都>右边序列的r[j]。所以,我们可知这种情况下,产生了mid - i + 1个逆序对。记录每次归并排序时发现的逆序对,并对1000000007求余,即可算出序列所有逆序对数量。


    代码

    #include "iostream"
    #include "string"
    #include "vector"
    using namespace std;
    
    long long Func(vector<int> &data, vector<int> &copy, int left, int right)
    {
        if (left == right)
        {
            return 0;
        }
        else
        {
            int mid = (right + left) / 2;
            long long res = 0;
            res += Func(data, copy, left, mid);
            res += Func(data, copy, mid + 1, right);
            int l = left, r = mid + 1, loc = left;
            while (l <= mid && r <= right)
            {
                if (data[l] <= data[r])
                {
                    copy[loc++] = data[l++];
                }
                else
                {
                    copy[loc++] = data[r++];
                    res += mid - l + 1;
                }
            }
            while (l <= mid)
            {
                copy[loc++] = data[l++];
            }
            while (r <= right)
            {
                copy[loc++] = data[r++];
            }
            for (int i = left; i <= right; i++)
            {
                data[i] = copy[i];
            }
            return res % 1000000007;
        }
    }
    
    int InversePairs(vector<int> data)
    {
        vector<int> copy(data);
        return Func(data, copy, 0, data.size() - 1);
    }
    
    int main()
    {
        vector<int> data = {1, 2, 3, 4, 5, 6, 7, 0};
        cout << InversePairs(data) << endl;
    }

    相关文章

      网友评论

          本文标题:数组中的逆序对-分治(归并排序)

          本文链接:https://www.haomeiwen.com/subject/jrisoftx.html