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

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

作者: 科研的心 | 来源:发表于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;
}

相关文章

  • 2018-03-16

    碰到的算法并查集逆序对归并排序分治算法

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

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

  • 排序

    1.归并排序 归并排序概念归并排序核心思想是分治,即将完整数组拆分成更小的数组,最小单位位1,每个小的数组排好序,...

  • 归并排序

    归并排序 归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。 将数组分解最小...

  • 排序与搜索: 归并排序

    归并排序 归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。 将数组分解最小...

  • 05-28:新刷算法题

    1、归并排序 数组逆序对的参考思路: https://zhuanlan.zhihu.com/p/107280674...

  • 算法读书笔记-排序算法-归并排序

    总结 归并排序主要用了分治的思想,通过将数组分成较小的段,对小段进行排序然后将小段合并起来,从而完成排序。归并排序...

  • 面试题总结

    算法思维 简述归并排序归并排序是一个使用分治策略来对乱序数组进行排序的算法,使用的思想是将乱序数组不断切割分解成若...

  • 基于左闭右开的乱序数组归并排序 2020-04-24(未经允许,

    归并排序代码模板 递归形式思路:二分nums数组后对nums的归并排序 = 对左侧数组归并排序+对右侧数组归并排序...

  • 快排,递归,非递归,三向切分,去掉边界条件

    快排 快排的思想: 典型的分治,将数组分成两个子数组,并且分别对子数组排序,且子数组的排序也是分治。 快排和归并排...

网友评论

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

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