题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
这个题目暴力破解的时间复杂度为O(n^2)所以肯定是不行的,主要利用了归并排序的思想,首先计算被二分的两部分有多少个逆序对,之后将二分的两部分排序,按照归并的方法,首先比较前半部分末尾的元素是否大于后半部分末尾的元素,如果大于则后半部分所有元素都可以和前面部分最后一个元素组成逆序,之后将前半部分向前移动一个元素继续比较,若不大于,则将后半部分的的末尾指针向前移动一个元素继续比较,在指针移动之前需要将元素压入栈中,直到一部分为空,将不为空的元素压入栈中,之后将栈的元素抛出存入数组中,完成数组的排序,递归即可.
class Solution {
public:
int InversePairs(vector<int> data) {
int count=0;
recursort(data,0,data.size()-1,count);
return count;
}
void recursort(vector<int> &data,int begin,int end,int &count)
{
if(begin>=end)
return;
stack<int> *sta=new stack<int>{};
int mid=begin+(end-begin)/2;
recursort(data,begin,mid,count);
recursort(data,mid+1,end,count);
int temp=mid;
while(temp>=begin&&end>=mid+1){
if(end >= mid + 1&&temp >= begin&&data[end]<data[temp])
{
count+=(end-mid)%1000000007;
count=count%1000000007;
sta->push(data[temp]);
--temp;
}
else if(end >= mid + 1&&temp >= begin&&data[end]>=data[temp])
{
sta->push(data[end]);
--end;
}
}
if(temp<begin)
{
while(end>=mid+1){
sta->push(data[end]);
--end;
}
}
else
{
while(temp>=begin){
sta->push(data[temp]);
--temp;
}
}
int i=begin;
while(!sta->empty())
{
data[i]=sta->top();
++i;
sta->pop();
}
delete sta;
}
};