数组中的逆序对
解法一:暴力解法,依次遍历每个值,再计算余下数字与其形成逆序的次数
解法二:仿照归并法。暴力解法在判断某个时,会多次遍历余下节点,仿照归并排序,每次分解依次,在合并的过程中进行计数,从两组待归并的最后一位开始合并,因为已经是排序好的,归并中对前面的数字就不必再比较而直接计算,还是要有图说明比较好
解法一
int InversePairs(int* data, int length) //暴力法
{
if (data == nullptr || length <= 1) return 0;
int cnt = 0;
for (int i=0;i<length;i++)
{
for (int j=i+1;j<length;j++)
{
if (data[j] < data[i])
cnt++;
}
}
return cnt;
}
解法二:
int InversePairs(int* data, int start, int end, int* tempArr)//归并法
{
if (start >= end) return 0;
int mid = (start + end) >> 1;
int cnt = 0;
cnt += InversePairs(data, start, mid, tempArr);
cnt += InversePairs(data, mid + 1, end, tempArr);
int* p1 = data + mid;
int* p2 = data + end;
int* p3 = tempArr + end;
while (true)
{
if (p1<data+start && p2>data+mid)
{
while (p2>data+mid)
{
*p3 = *p2;
p3--;
p2--;
}
}
else if (p1>=data+start && p2<=data+mid)
{
while (p1>=data+start)
{
*p3 = *p1;
p3--;
p1--;
}
}
else if (p1>=data && p2>data+mid)
{
if (*p1>*p2)
{
cnt += p2 - (data + mid);
*p3 = *p1;
p3--;
p1--;
}
else
{
*p3 = *p2;
p3--;
p2--;
}
}
else
break;
}
for (int i=start;i<=end;i++)
data[i] = tempArr[i];
return cnt;
}
int InversePairs_merge(int* data, int length) //归并法
{
if (data == nullptr || length <= 1) return 0;
int* tempArr = new int[length]();
return InversePairs(data, 0, length - 1, tempArr);
}