题目:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对,输入一个数组,
求出这个数组中的逆序对的总数P。对将P对1000000007取模的结果输出。
对于50%的数据,size<=10^4
对于75%的数据,size<=10^5
对于100%的数据,size<=2*10^5
解法:
1、实质就是一个归并排序的过程
2、在归并排序的过程中的merge部分,假设相邻的两个排好序的子数组为A=[1,3,6,7],B=[2,4,5,8]
仅完成排序功能时候:依次从头开始比较A1 B1,把小的放入temp数组中。
比较顺序为1<2,1放入temp. 2<3,2放入temp ,3<4,3放入temp,
4<6,4放入temp, 5<6 ,5放入temp,6<8,6放入temp,
7<8,7放入temp,数组A的所有数字比较完毕。 把B数组中剩下的数字依次放入temp中。
3、在步骤2中插入一个数 逆序对的过程。出现A数组中的数字大于B数组中的数字时候。
例如A[1]=3 >B[0]=2,那么在A数组中元素3后面所有的元素都能构成逆序对。即(3,2)(4,2)(6,2)(7,2)
所以个数count为mid-first+1. 整个比较过程中,只有这种情况产生逆序对,最后用一个主函数中的变量在,其他函数
中进行引用,一直迭代相加 即可最后的逆序对。也可以用全局变量来定义count
代码如下:
int InversePairs(vector<int> data) {
if(data.empty()||data.size()<=1)
return 0;
long long count =0;
split(data,0,data.size()-1,count);
return count;
}
void split(vector<int> &data,int begin,int end,long long &count)
{
if(begin>=end)
return;
int mid = begin +(end-begin)/2;
split(data,begin,mid,count);
split(data,mid+1,end,count);
merge(data,begin,mid,end,count);
}
void merge(vector<int> &data,int begin,int mid, int end,long long &count)
{
int first = begin;
int second = mid+1;
int index = 0;
int temp[end-begin+1];
while(first<=mid && second<=end)
{
if(data[first]<=data[second])
temp[index++] = data[first++];
else //前面数组中的某个数大于后面数组中某个数的情况
{
temp[index++] =data[second++];
count = (count+(mid-first+1))%1000000007;
}
}
while(first<=mid)
temp[index++] = data[first++];
while(second<=end)
temp[index++] =data[second++];
for(int i =0;i<index;i++)
data[i+begin] = temp[i];
}