求逆序对数

https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题目描述

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

输入描述:

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

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

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

示例1

输入

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

输出

7
思路: 使用归并排序,merge过程中 因为保证了 左侧数组 与 右侧数组 分别有序,所以在merge过程中统计逆序对数
对于数组 :
  如果 a[i] > a[j] then j ++; 这样保证了 一旦出现 a[i] <= a[j] 的时候, a[i] > a[m + 1 -> j - 1] 得到由(
a[i] , a[m+1 : j - 1]
)构成的逆序对数 j - 1 - m 对;
#include <iostream>
#include <vector>
#include <cstdio>
#define DEBUG

using namespace std;

#define MOD 1000000007
class Solution {
public:
    int cnt = 0;
    void merge(int l, int m, int r, vector<int>& a)
    {
        int i = l, j = m + 1, k = r;
        vector<int>t;
        while(i <= m || j <= r)
        {
            if(i <= m && j <= r)
            {
                if(a[i] > a[j]){
                    t.push_back(a[j ++]);
                }else{
                    cnt = ( cnt % MOD + ( j  - m - 1) % MOD) % MOD;
                    t.push_back(a[i ++]);
                }
            }
            else if(i <= m)
            {
                 cnt = ( cnt % MOD + ( j  - m - 1) % MOD) % MOD;
                 t.push_back(a[i ++]);
            }
            else
            {
                t.push_back(a[j ++]);
            }
        }
        for(int i = l; i <= r; i ++)
            a[i] = t[i - l];
    }

    void divide(int l, int r, vector<int>& a)
    {
        if (l < r){
            int m = l + (r - l) / 2;
            divide(l, m, a);
            divide(m + 1,  r, a);
            merge(l, m,  r, a);/*
            cout << "l:" <<l << "   m + 1: "<< m + 1 << "    r:" << r<<endl;
            cout <<"cnt= " <<cnt <<endl;
            for(int i = l; i <= r; i ++)
            {
                cout << a[i] << " ";
            }cout <<endl;*/
        }
    }

    int InversePairs(vector<int>& data) {
        divide(0, data.size() - 1, data);
        return cnt;
    }
};

int main()
{
    #ifdef DEBUG
        freopen("input.txt", "r", stdin);
    #endif // DEBUG
    vector<int>d;
    int n, t;
    cin>>n;
    for(int i = 0; i < n; i ++){
        cin>>t;
        d.push_back(t);
    }
    Solution sol;
    cout << sol.InversePairs(d) << endl;
    for(int i = 0; i < n; i ++)
        cout << d[i] << " " ;
    return 0;
}
/*
7
4 5 6 7 3 4 5
*/

 

posted on 2017-10-23 21:18  暴力的轮胎  阅读(418)  评论(0编辑  收藏  举报

导航