题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
解题思路
思路一:暴力搜索,一次判断每一个数,其之后的数有没有比它小的,若有则计数加一。时间O(n^2)
思路二:利用归并排序方法,在归并的时候,计算逆序对数目。具体过程看代码。 时间O(nlogn)
实现代码
class Solution {
public:
int InversePairs(vector<int> data) {
if(data.empty())
return 0;
int len = data.size();
vector<int> copy(len,0);
int result=0;
result = mergeSort(data, copy,0,len-1);
return result;
}
int mergeSort(vector<int> &data, vector<int> ©, int start, int end)
{
if(start == end)
{
copy[start] = data[end];
return 0;
}
int mid = (end+start)/2;
int left = mergeSort(data,copy,start, mid);
int right = mergeSort(data,copy, mid+1,end);
int count = merge(data,copy,start,mid,end);
return left + right +count;
}
int merge(vector<int> &data, vector<int> ©, int start, int mid, int end)
{
int lBegin = start, lEnd = mid;
int rBegin = mid+1, rEnd = end;
int k=end;
int count = 0;
while(lEnd >= lBegin && rEnd >= rBegin)
{
if(data[lEnd] > data[rEnd])
{
count += rEnd-rBegin+1;//计算逆序对
copy[k--] = data[lEnd--];
}
else
copy[k--] = data[rEnd--];
}
while(lBegin <= lEnd)
copy[k--] = data[lEnd--];
while(rBegin <= rEnd)
copy[k--] = data[rEnd--];
for(int i=start ; i<=end; i++)
data[i] = copy[i];
return count;
}
};