数组中的逆序对(c++)

参考博客:https://www.cnblogs.com/wanglei5205/p/8893700.html
题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

对于%100的数据,size<=2*10^5

思路:
基于归并排序的思想统计逆序对:先把数组分割成子数组,再子数组合并的过程中统计逆序对的数目。统计逆序对时,先统计子数组内部的逆序对的数目,再统计相邻子数组的逆序对数目。
利用归并排序:比如 9 5 7 4把长度为4的数组分解成长度为2的分组,把长度为2的数组分解成长度为1的数组->95 74 ->9 5 7 4
合并排序->59 74 ->4579主要的算法在merge里面 因为合并排序后的数据比如:6789 2345。。。6大于2则6789均大于2,cnt+=4;6大于3则6789均大于3,cnt+=4;6大于3则6789均大于3,cnt+=4;6大于4则6789均大于4,cnt+=4;
详见代码:

#include
#include
using namespace std;
int cnt = 0;
void merge(vector<int>& data, int start, int mid, int end)
{
     
	vector<int> tmp;                    //tmp临时变量用来存储当前[start,end]段排序后的结果,然后再赋值给data
	int i = start, j = mid + 1;         //采用的是引用传递,所以修改的是原数组
	while (i <= mid&&j <= end)
	{
     
		if (data[i] > data[j])         //6789   2345   6大于2  那么cnt+=4   tmp.push_back(2)
		{
     
			cnt = (cnt + mid - i + 1) % 1000000007;  ///对1000000007取余是为了防止整形溢出
			tmp.push_back(data[j++]);
		}
		else
			tmp.push_back(data[i++]);  //6789   10 11 12 13   6小于10  那么tmp.push_back(6)
	}								   //tmp就是存data(start,end)区间内从小到大的存储起来
	while (i <= mid) {
     
		tmp.push_back(data[i++]);//待合并排序的数据比如6789  2345那么这个循环执行的就是				
								//tmp.push_back(7)tmp.push_back(8)tmp.push_back(9)
	}
	while (j <=end) {
     
		tmp.push_back(data[j++]);
	}
	for (int i = 0; i < tmp.size(); ++i)
	{
     
		data[start + i] = tmp[i];
	}
}
void mergesort(vector<int>& data, int start, int end)   //分解
{
     
	if (start < end)
	{
     
		int mid = (start + end) >> 1;
		mergesort(data, start, mid );
		mergesort(data, mid+1,end);
		merge(data, start, mid, end); //调用归并排序的合并排序函数
	}
}
int InversePairs(vector<int> data) {
     
	int n = data.size();
	if (n != 0)
	{
     
		mergesort(data, 0, n - 1);   //调用归并排序的分解函数
	}
	return cnt;
}
void main()
{
     
	vector<int> data = {
      364, 637, 341, 406, 747, 995, 234, 971, 571, 219, 993, 407, 416, 366, 315, 301, 601, 650, 418, 355, 460, 505, 360, 965, 516, 648, 727, 667, 465, 849, 455, 181, 486, 149, 588, 233, 144, 174, 557, 67, 746, 550, 474, 162, 268, 142, 463, 221, 882, 576, 604, 739, 288, 569, 256, 936, 275, 401, 497, 82, 935, 983, 583, 523, 697, 478, 147, 795, 380, 973, 958, 115, 773, 870, 259, 655, 446, 863, 735, 784, 3, 671, 433, 630, 425, 930, 64, 266, 235, 187, 284, 665, 874, 80, 45, 848, 38, 811, 267, 575 };
	//答案为:2519
	//vector data = { 1,2,3,4,5,6,7,0 };
	//答案为:7
	//vector data = { 5,3,1,4,2 };
	//答案为:7
	cout << InversePairs(data) << endl;
	cin.get();
	return;
}

你可能感兴趣的:(c++,数据结构)