题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数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
思路:暴力肯定行不通的,所以才去归并的方法,模拟归并排序的过程,在每次左右合并的时候,进行逆序对个数计算(例如左部分第一个大于右部分第一个,则说明所有左部分都可以和右部分第一个构成逆序对,所有num+=左部分长度-p1)
class Solution {
private:
int num=0;
void merge(int start, int mid, int end,vector<int>& data)
{
int *left_data = new int[mid - start + 1];
int *right_data = new int[end - mid];
int p = 0,p1=0,p2=0;
for (int i = start; i <= mid ; ++i)
left_data[p++] = data[i];
p = 0;
for (int i = mid + 1; i <= end; ++i)
right_data[p++] = data[i];
p = start;
while (p1 < mid-start+1&&p2 <end-mid)
{
if (left_data[p1] > right_data[p2])
{
num +=mid-start+1-p1;//注意一下哦
num %= 1000000007;
data[p++] = right_data[p2++];
}
else
data[p++] = left_data[p1++];
}
while (p1 <mid-start+1)
data[p++] = left_data[p1++];
while (p2 <end-mid)
data[p++] = right_data[p2++];
delete[] left_data;
delete[] right_data;
}
void mergeSort(int start, int end, vector<int>&data)
{
if (start < end)
{
int mid = (start + end) / 2;
mergeSort(start, mid, data);
mergeSort(mid + 1, end, data);
merge(start, mid, end, data);
}
}
public:
int InversePairs(vector<int> data)
{
mergeSort(0, data.size() - 1, data);
return num % 1000000007;
}
};