数组中的逆序对

来源:互联网 发布:消防知识知多少日记 编辑:程序博客网 时间:2024/05/06 13:15

题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数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


1、暴力法

//本来是个经典问题//这么暴力都能通过。。。 数据规模竟然这么小。。。那这题目出来何用。。。class Solution {public:    int InversePairs(vector<int> d) {        int r = 0;        for(int i = 0; i < d.size(); ++i){            for(int j = 0; j < i; ++j) if(d[j] > d[i]) ++r;        }        return r;    }};

2、归并思想


/*参考《剑指offer》,有两种思路。第一就是暴力求解法,时间复杂度为o(n^2),空间复杂度o(1)第二种思路就是使用归并排序的思想进行处理,时间复杂度o(nlog(n)),空间复杂度0(n)*/class Solution {public:    int InversePairsCore(vector<int>& data,vector<int>& copy,int begin,int end)    {        if(begin==end)        {            copy[begin]=data[begin];            return 0;        }        //将数组拆分成两部分        int length=(end-begin)/2;        //这里使用的下标法,下面要用来计算逆序个数;也可以直接使用mid=(start+end)/2         //分别计算左边部分和右边部分        int left=InversePairsCore(copy,data,begin,begin+length)%1000000007;        int right=InversePairsCore(copy,data,begin+length+1,end)%1000000007;         //进行逆序计算        int i=begin+length;//前一个数组的最后一个下标        int j=end;//后一个数组的下标                int copy_index=end;//辅助数组下标,从最后一个算起        int count=0;                while(i>=begin&&j>=begin+length+1)        {            if(data[i]>data[j])            {                copy[copy_index--]=data[i--];                //统计长度                count+=j-begin-length;                if(count>1000000007)//数值过大求余                    count%=1000000007;            }            else                copy[copy_index--]=data[j--];        }                while(i>=begin)            copy[copy_index--]=data[i--];        while(j>=begin+length+1)            copy[copy_index--]=data[j--];                return left+right+count;    }    int InversePairs(vector<int> data) {        int len=data.size();        if(len<=1) return 0;//如果少于等于1个元素,直接返回0                //初始化该数组,该数组作为存放临时排序的结果,最后要将排序的结果复制到原数组中        vector<int> copy(data.begin(),data.end());                        int begin=0,end=len-1;                return InversePairsCore(data,copy,begin,end)%1000000007;    }};


下边这个注意和上边的区别


/*参考《剑指offer》,有两种思路。第一就是暴力求解法,时间复杂度为o(n^2),空间复杂度o(1)第二种思路就是使用归并排序的思想进行处理,时间复杂度o(nlog(n)),空间复杂度0(n)*/class Solution {public:    int InversePairsCore(vector<int>& data,vector<int>& copy,int begin,int end)    {        if(begin==end)        {            copy[begin]=data[begin];            return 0;        }        //将数组拆分成两部分        int length=(end-begin)/2;        //这里使用的下标法,下面要用来计算逆序个数;也可以直接使用mid=(start+end)/2         //分别计算左边部分和右边部分        int left=InversePairsCore(data,copy,begin,begin+length)%1000000007;        int right=InversePairsCore(data,copy,begin+length+1,end)%1000000007;         //进行逆序计算        int i=begin+length;//前一个数组的最后一个下标        int j=end;//后一个数组的下标                int copy_index=end;//辅助数组下标,从最后一个算起        int count=0;                while(i>=begin&&j>=begin+length+1)        {            if(data[i]>data[j])            {                copy[copy_index--]=data[i--];                //统计长度                count+=j-begin-length;                if(count>1000000007)//数值过大求余                    count%=1000000007;            }            else                copy[copy_index--]=data[j--];        }                while(i>=begin)            copy[copy_index--]=data[i--];        while(j>=begin+length+1)            copy[copy_index--]=data[j--];                for(int i=begin;i<=end;i++)            data[i]=copy[i];                return left+right+count;    }    int InversePairs(vector<int> data) {        int len=data.size();        if(len<=1) return 0;//如果少于等于1个元素,直接返回0                //初始化该数组,该数组作为存放临时排序的结果,最后要将排序的结果复制到原数组中        vector<int> copy(len,0);        int begin=0,end=len-1;                return InversePairsCore(data,copy,begin,end)%1000000007;    }};



0 0
原创粉丝点击