描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007
数据范围: 对于 50\%50% 的数据, size\leq 10^4size≤104
对于 100\%100% 的数据, size\leq 10^5size≤105
数组中所有数字的值满足 0 \le val \le 10000000≤val≤1000000
要求:空间复杂度 O(n)O(n),时间复杂度 O(nlogn)O(nlogn)
输入描述:
题目保证输入的数组中没有的相同的数字
示例1
输入:
[1,2,3,4,5,6,7,0]
复制返回值:
7
思路:
1.利用归并排序的思路,在比较的同时,找到逆序对
2.当data[i]>data[j]时,说明,[i-mid]下标的都是大于data[j]的,所以此时可以构成mid-i+1个逆序对
class Solution {
public:
vector<int> tmp;
int res=0;
int mod=1000000007;
int InversePairs(vector<int> data) {
if(data.size()<2)return 0; //小于2个没有
tmp.resize(data.size()); //分配空间
mergeSort(data,0,data.size()-1);
return res;
}
void mergeSort(vector<int> &data,int left,int right){//排序部分
if(right<=left)return;
int mid=(left+right)/2;
mergeSort(data, left,mid); //归并排序
mergeSort(data, mid+1,right);
merge(data,left,mid,right);
}
void merge(vector<int> &data,int left,int mid,int right){ //合并部分
int i=left,j=mid+1,k=0;
while(i<=mid && j<=right){
if(data[i]>data[j]){
tmp[k++]=data[j++];
res+=(mid-i+1); //data[i] >data[j]说明,[i-mid]下标的都是大于data[j]的
res%=mod; //防止溢出,提前mod
}else{
tmp[k++]=data[i++];
}
}
while(i<=mid){
tmp[k++]=data[i++];
}
while(j<=right){
tmp[k++]=data[j++];
}
for(i=left,k=0;i<=right;i++,k++){
data[i]=tmp[k];
}
}
};