题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数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
思路
使用归并排序( O ( n log n ) O(n\log n) O(nlogn)),对数组中的两个区间进行比较排序的时候就是统计逆序对的时候,需要注意的是这个两个区间已经是顺序的,且是从大到小排序的,具体思想查看个人博客
AC代码
#include <iostream>
#include <vector>
using namespace std;
class Solution
{
public:
int InversePairs(vector<int> data)
{
long long res = 0;
solve(0, data.size() - 1, data, res);
return res % 1000000007;
}
void solve(int low, int high, vector<int> &data, long long &res) //注意data,res要传引用
{
if (low < high)
{
int mid = (low + high) / 2;
solve(low, mid, data, res);
solve(mid + 1, high, data, res);
merge_sort(low, high, mid, data, res);
}
}
void merge_sort(int begin, int end, int mid, vector<int> &data, long long &res) //注意data,res要传引用
{
int temp[200004]; //辅助数组,将原来的数组拍好序复制到temp中
int i = begin;
int j = mid + 1;
int k = begin; //辅助数组的索引
while (i <= mid && j <= end)
{
if (data[i] > data[j]) //低位大于高位,可以记录逆序对
{
res = res + end - j + 1; //因为从大到小排序的,如果低位的数大于高位,那么当前的数肯定大于高位后面的数
temp[k++] = data[i++];
}
else
temp[k++] = data[j++];
}
//将剩余的数复制到temp数组的后面
while (i <= mid)
temp[k++] = data[i++];
while (j <= end)
temp[k++] = data[j++];
//更新data数组
for (int i = begin; i <= end; i++)
{
data[i] = temp[i]; //注意,我们的temp数组是从k = begin开始操作的
}
}
};
int main()
{
vector<int> data = {1, 2, 3, 4, 5, 6, 7, 0};
Solution so;
cout << so.InversePairs(data) << endl;
return 0;
}