zoukankan      html  css  js  c++  java
  • 数组中的逆序对

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

    输入描述:
    题目保证输入的数组中没有的相同的数字

    数据范围:

    对于%50的数据,size<=10^4
    对于%75的数据,size<=10^5
    对于%100的数据,size<=2*10^5

    【思路】基于归并排序的思想统计逆序对:先把数组分割成子数组,再子数组合并的过程中统计逆序对的数目。统计逆序对时,先统计子数组内部的逆序对的数目,再统计相邻子数组的逆序对数目。

    注:图中省略了最后一步,即复制第二个子数组最后剩余的4到辅助数组中。(a) P1指向的数字大于P2指向的数字,表明数组中存在逆序对。P2指向的数字是第二个子数组的第二个数字,因此第二个子数组中有两个数字比7小。把逆序对数目加2,并把7复制到辅助数组,向前移动P1和P3。(b) P1指向的数字小于P2指向的数字,没有逆序对。把P2指向的数字复制到辅助数组,并向前移动P2和P3. (c) P1指向的数字大于P2指向的数字,因此存在逆序对。由于P2指向的数字是第二个子数组的第一个数字,子数组中只有一个数字比5小。把逆序对数目加1,并把5复制到辅助数组,向前移动P1和P3。

    #include <iostream>
    #include <vector>
    using namespace std;
    
    class Solution{
    public:
        int count=0;
        int InversePairs(vector<int> data)
        {
            // 检查边界条件
            if(data.size() != 0)
            {
                MergeSort(data,0,data.size()-1);
            }
            return count;
        }
    
    private:
        void MergeSort(vector<int> a, int l, int r)
        {
            /* 将长度为n的输入序列分成两个长度为n/2的子序列 */
            if (l < r)
            {
                /* 中间元素*/
                int m = (l + r) >>1;
    
                // 递归拆分
                MergeSort(a, l, m);
                MergeSort(a, m + 1, r);
    
                // 递归合并
                Merge(a, l, m, r);
            }
        }
        void Merge(vector<int> a, int l, int m, int r)
        {
            vector<int> t;
            //int p = 0;    /* p指向辅助数组 */
            int i = l;    /* i指向第一个子表 */
            int j = m + 1;/* j指向第二个子表 */
    
            /* 两个子表都不为空时 */
            while(i <= m && j <= r)
            {
                /* 取关键字小的元素转移至临时数组 */
                if (a[i] > a[j])
                {
                    t.push_back(a[j++]);
                    count=(count+m-i+1)%1000000007;
                }
                else
                    t.push_back(a[i++]);
            }
    
            while(i <= m) t.push_back(a[i++]);/* 将非空的输入区间转移至输出区间 */
            while(j <= r) t.push_back(a[j++]);
    
            for (i = 0; i < t.size(); i++) a[l + i] = t[i];/* 归并完成后将结果复制到原输入数组 */
        }
    };
    
    int main()
    {
        vector<int> a = {8,7,6,5,455,88,888,9999,546,46548,1315,445,554,111,5222,2264,8,331,454548};
        Solution solution;
        solution.InversePairs(a);
    return 0;
    }
  • 相关阅读:
    jenkins系列---【linux安装nodejs】
    jenkins系列---【jenkins+gitlab+springCloud实现CI和CD】
    jenkins系列---【jenkins创建账号、分配角色】
    idea系列---【启动的时候报:Error running FinanceApplication. Command line is too long. Shorten the command line via JAR manifest or via a classpath file and rerun】
    ubuntu apt-get install xxx时一直报错E: Unable to locate package xxxxxxx
    mysql binlog 使用
    python项目导出所需要的依赖库
    mysql 导入sql文件时编码报错
    mysqldumps 远程备份
    pymongo的基本使用
  • 原文地址:https://www.cnblogs.com/zhudingtop/p/11377274.html
Copyright © 2011-2022 走看看