在數組中的兩個數字,如果前面一個數字大于后面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數P。并將P對1000000007取模的結果輸出。 即輸出P%1000000007
這個問題就是檢查每個數后面有多少個比他小的數字。我們當然可以遍歷這個數組,找到一個數字,然后再遍歷的查找后面的數組中有多少個數字比它小。但是這樣就n^2的時間了。
那么我們可以使用歸并排序來解決,時間O(nlgn)。使用歸并排序,我們可以找到兩個數字的逆序對,再找到四個數字的逆序對。。。一直找到n個數字。
class Solution
{
public:
//使用歸并,從小范圍到大范圍的找出逆序對
int InversePairs(vector<int>data)
{
int length = data.size();
if(length<=0)
return 0;
vector<int> copy;
for(int i=0;i<length;i++)
copy.push_back(data[i]);
long long count = InversePairsCore(data,copy,0,length-1);
return count%100000007;
}
long long InversePairsCore(vector<int>& data,vector<int>& copy,int start,int end)
{
if(start == end)
{
copy[start] = data[start];
return 0;
}
int length=(end-start)/2;
long long left = InversePairsCore(copy,data,start,start+length);
long long right = InversePairsCore(copy,data,start+length+1,end);
//開始歸并
int i=start + length;
int j = end;
int indexcopy = end;//每次都是從最后一點開始放元素
long long count;
while(i>=start&&j>=start+length+1)
{
if(data[i]>data[j])
{
copy[indexcopy--] = data[i--];
count = count+j-start-length;//比這個范圍內的數字都大。
}
else//如果data i 小于data j,那就沒有逆序對
copy[indexcopy--] = data[j--];
}
for(;i>=start;i--)
copy[indexcopy--] = data[i];
for(;j>=start+length+1;j--)
copy[indexcopy--] = data[j];
return left+right+count;
}
}