题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于50%的数据,size<=10^4
对于75%的数据,size<=10^5
对于100%的数据,size<=2*10^5
示例1
输入
1,2,3,4,5,6,7,0
输出
7
算法:
先把数组分割成子数组,统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目,实际上就是归并排序,只不过加上了逆序对的统计。
// 法一:merge操作需要拷贝回去的算法
// aux一开始不需要复制一份data数据,直接初始化为0即可
class Solution {
public:
int InversePairs(vector<int> data) {
int n = data.size();
if (n == 0 || n == 1) return 0;
vector<int> aux(n, 0);
return mergeSort(data, aux, 0, n - 1);
}
private:
int mergeSort(vector<int>& data, vector<int>& aux, int start, int end){
if (start == end) {
aux[start] = data[start];
return 0;
}
int mid = start + (end - start) / 2;
long long left = mergeSort(data, aux, start, mid);
long long right = mergeSort(data, aux, mid + 1, end);
return (left + right + merge(data, start, mid, mid + 1, end, aux)) % 1000000007;
}
int merge(vector<int>& data, int start, int end, int start2, int end2, vector<int>& aux){
int i = end, j = end2, index = end2;
long long count = 0;
while (i >= start && j >= start2) { //都指向最后一位
if (data[i] > data[j]) {
count += j - start2 + 1;
aux[index--] = data[i--];
} else {
aux[index--] = data[j--];
}
}
for (; i >= start; i--) {
aux[index--] = data[i];
}
for (; j >= start2; j--) {
aux[index--] = data[j];
}
while (start <= end2) { //回拷贝
data[start] = aux[start];
start++;
}
return int(count % 1000000007);
}
};
//法二:merge操作不需要拷贝回去的算法
//一开始需要将data信息复制一份到aux
class Solution {
public:
int InversePairs(vector<int> data) {
int n=data.size();
if(n==0 || n==1) return 0;
vector<int> aux;
for(int i=0;i<n;i++)
aux.push_back(data[i]);
return mergeSort(data,aux,0,n-1);
}
private:
//注意函数调用:aux-->data data-->aux
int mergeSort(vector<int>& data,vector<int>& aux,int start,int end){
if(start==end){
aux[start]=data[start];
return 0;
}
int mid=start+(end-start)/2;
long long left=mergeSort(aux,data,start,mid); //aux、data顺序相对法一对调了
long long right=mergeSort(aux,data,mid+1,end); //同上
return (left+right+merge(data,start,mid,mid+1,end,aux))%1000000007;
}
int merge(vector<int>& data,int start,int end,int start2,int end2,vector<int>& aux){
int i=end;
int j=end2;
int index=end2;
long long count=0;
while(i>=start && j>=start2){ //都指向最后一位
if(data[i]>data[j]){
count+=j-start2+1;
aux[index--]=data[i--];
}else{
aux[index--]=data[j--];
}
}
for(;i>=start;i--){
aux[index--]=data[i];
}
for(;j>=start2;j--){
aux[index--]=data[j];
}
return int(count%1000000007);
}
};