【剑指offer】数组中的逆序对
题目链接:数组中的逆序对
题意:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
题解:因为这次的数据到了2*10^5。暴力肯定是不太行的。所以我们需要用到归并排序进行优化。
大概过程如下。(灵魂画手)
归并排序的合并过程每一次计算逆序的对数。这样我们可以得到。
归并总对数 = 左边归并逆序对数 + 右边归并逆序对数 + 左右归并产生的逆序对数
代码:
1 class Solution { 2 public: 3 const int mod = 1000000007; 4 long long int cnt = 0; 5 void Merge(vector<int> &data,vector<int> ©,int begin,int mid,int end){ 6 int start = begin; 7 int l = begin; int r = mid + 1; 8 while(l <= mid && r <= end){ 9 if(data[l] < data[r]) copy[begin++] = data[l++]; 10 else{ 11 copy[begin++] = data[r++]; 12 cnt += mid - l + 1; 13 } 14 } 15 while(l <= mid) copy[begin++] = data[l++]; 16 while(r <= end) copy[begin++] = data[r++]; 17 //数组同一 18 while(start <= end){ 19 data[start] = copy[start]; 20 start++; 21 } 22 } 23 void MSort(vector<int> &data,vector<int> ©,int begin,int end){ 24 int mid; 25 if(begin < end){ 26 mid = ( begin + end)/2; 27 MSort(data,copy,begin,mid); //左 28 MSort(data,copy,mid+1,end); //右 29 Merge(data,copy,begin,mid,end); //合并 30 } 31 } 32 int InversePairs(vector<int> data) { 33 vector<int> copy = data; 34 int len = data.size(); 35 MSort(data, copy, 0, len - 1); 36 return cnt % mod; 37 } 38 };