题解 | #数组中的逆序对#

数组中的逆序对

https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5

#include <algorithm>
#include <vector>
#define MOD 1000000007
class Solution {
public:
    int InversePairs(vector<int> data) {
        vector<int> tmp;
        for(int i = 0;i < data.size();i++)
            tmp.push_back(data[i]);
        return sort(data, 0, data.size(), tmp);
    }
private:
    int Merge(vector<int> &data, int left, int mid, int right,vector<int> &tmp){
        int p = 0;
        int i = left;
        int j = mid;
        int inverse_cnt = 0; 
        while(i<mid&&j<right){
            if(data[i]<=data[j])
                tmp[p++] = data[i++];
            else{
                inverse_cnt += mid - i;
                tmp[p++] = data[j++];
            }
        }
        while(i<mid)
            tmp[p++] = data[i++];
        while (j<right) 
            tmp[p++] = data[j++];
        p = 0;
        for(i = left;i<right;i++)
            data[i] = tmp[p++];
        return inverse_cnt;
    }
    int sort(vector<int> &data, int left, int right,vector<int> &tmp){
        if(right-left==1){
            return 0;
        }
        int mid = (left+right)/2;
        int inverse1 = 0;
        int inverse2 = 0;
        inverse1 = sort(data, left, mid, tmp) % MOD;
        inverse2 = sort(data, mid, right, tmp) % MOD;
        return (inverse1+inverse2+Merge(data, left, mid, right,tmp)%MOD) % MOD;
    }
};

这个题就是用归并排序的方法,核心思想就是数组一分为二,先求左边的逆序数,再求右边的逆序数,再求左右之间产生的逆序数。将三者相加就是该数组的逆序数。依次递归,当数组只有一个数字时,逆序数为0。用归并排序是为了求左右两边之间产生的逆序数。思路如下:假设a,b为有序数组,则将a,b merge的时候,如果出现b当前元素(索引为j)比a当前元素(索引为i)小的情况,就说明a当前元素及后面的所有元素都比b当前的元素大,也就是当前的b元素产生的逆序数为a.size() - i. 由此可求出a和b合并时产生的逆序数

全部评论

相关推荐

收到了小米的实习offer,犹豫是否要去。。。
认真搞学习:雷总还当过首富呢,公司不算大厂算独角兽吗
点赞 评论 收藏
分享
05-12 16:04
已编辑
江西财经大学 Java
点赞 评论 收藏
分享
05-12 17:28
已编辑
门头沟学院 硬件开发
ldf李鑫:不说公司名祝你以后天天遇到这样的公司
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务