剑指Offer:数组中的逆序对

数组中的逆序对


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


这可能是我最近几天最大的收获。
此题加深了我对归并排序的理解,从过程到时间复杂度,空间复杂度。我还需要专门研究。下面先记录此题:
1、归并排序实现,数组分割与合并,递归。
2、在合并过程中,前数组与后数组不断取小者填入缓存,然后将缓存copy到数组中。
3、逆序数对的统计便发生在第二步,取后者的时候,是不是就代表着前者中现有的剩余数字都比此时要取得数字大,即构成逆序对。

Reference:
白话经典算法系列之五 归并排序的实现
http://blog.youkuaiyun.com/morewindows/article/details/6678165/
白话经典算法系列之九 从归并排序到数列的逆序数对(微软笔试题)
http://blog.youkuaiyun.com/morewindows/article/details/8029996


class Solution {
public:
    int InversePairs(vector<int> data) {
        if(data.empty())    return 0;
        int sz=data.size();
        vector<int> temp(sz);
        mergeSort(data,temp,0,sz-1);
        return count%1000000007 ;
    }
    /*归并排序:不断分割,最小时开始合并。
    *一定要有序才能正确计算。
    *逆序数对:当取后者数时,前者数剩余个数便是此数的逆序对个数
    */
private:
    //分割
    void mergeSort(vector<int> &data,vector<int> &temp,int beg,int end){
        if(beg<end){
            int mid=(beg+end)/2;
            mergeSort(data,temp,beg,mid);
            mergeSort(data,temp,mid+1,end);
            mergeArray(data,temp,beg,mid,end);
        }
    }
    //合并
    void mergeArray(vector<int> &data,vector<int> &temp,int beg,int mid,int end){
        int f1{beg},f2{mid+1},f{beg};
        while(f1<=mid&&f2<=end){
            if(data[f1]<data[f2]){
                temp[f++]=data[f1++];
            }
            else{
                temp[f++]=data[f2++];
                count+=(mid-f1+1);
            }
        }
        while(f1<=mid){
            temp[f++]=data[f1++];
        }
        while(f2<=end){
            temp[f++]=data[f2++];
        }
        for(int i=beg,j=beg;i<=end;++i,++j){
            data[i]=temp[j];
        }
    }
    long long  count=0;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值