用到了归并排序的思想,有关归并排序:
如果前半部分的数组中一个数大于后半部分的某个数,因为子数组是排好序的,所以肯定大于后半部分某数之前的全部数,即j-mid,见代码中,这就是i对应的逆序数目。
class Solution {
public:
long long InversePairsCore(vector<int>& data, vector<int>& copy, int start, int end)
{
if (start == end)
return 0;
long long mid = (start + end) >>1;
long long left = InversePairsCore( copy,data, start, mid); //这里把copy和data换了一下位置,滚动数组的思想?
long long right = InversePairsCore( copy,data, mid + 1, end);
long long i = mid;
long long j = end;
long long indexcopy = end;
long long count = 0;
while (i >= start && j > mid)
{
if (data[i] > data[j])
{
copy[indexcopy--] = data[i--];
count += j - mid; //见上方黑粗字
}
else
copy[indexcopy--] = data[j--];
}
while (i >= start)
copy[indexcopy--] = data[i--];
while (j > mid)
copy[indexcopy--] = data[j--];
//for(int s=start;s<=end;s++)
// data[s]=copy[s];
return left + right + count;
}
int InversePairs(vector<int> data)
{
auto t = data.size();
if (t == 0)
return 0;
vector<int> copy(data);
long long count = InversePairsCore(data, copy, 0, t-1);
copy.clear();
return count % 1000000007;
}
};
void Merge(int data[], int copy[], int start, int end,int mid)
{
int i = start;
int j = mid+1;
int k = 0;
while (i <= mid && j <=end)
{
if (data[i] < data[j])
{
copy[k++] = data[i++];
}
else
copy[k++] = data[j++];
}
while (i <= mid)
copy[k++] = data[i++];
while (j <= end)
copy[k++] = data[j++];
for (int i = 0; i < k;i++)
{
data[start + i] = copy[i];
}
}
void mergesort(int data[], int copy[], int start, int end)
{
if (start < end)
{
int mid = (start + end) >> 1;
mergesort(data, copy, start, mid);
mergesort(data, copy, mid + 1, end);
Merge(data, copy, start, end,mid);
}
}
bool mergesort(int a[],int n)
{
int *p = new int[n];
if (p == NULL)
return false;
mergesort(a,p, 0, n - 1);
delete[] p;
return true;
}