我尝试使用合并排序解决此问题,但我的解决方案有问题。我在合并数组时检查了反转次数。 有人可以帮我找到问题吗?
void merge(int arr[], int l, int m, int r)
{
int n1=m-l+1;
int n2=r-m;
int left[(n1+1)];
int right[(n2+1)];
for(int i=0;i<n1;i++){
left[i]=arr[l+i];
}
for(int j=0;j<n2;j++){
right[j]=arr[m+j+1];
}
left[n1]=INT_MAX;
right[n2]=INT_MAX;
int i=0, j=0;
//int inv=0;
for(int k=l;k<=r;k++){
if(left[i]<=right[j]){
arr[k]=left[i];
i++;
}
else{
arr[k]=right[j];
j++;
inv+=(m-i);
}
}
//return inv;
}
void mergeSort(int arr[], int l, int r) {
int inv=0;
if (l < r) {
int m = l+(r-l)/2;
mergeSort(arr, l, m);
mergeSort(arr, m+1, r);
merge(arr, l, m, r);
}
// return inv;
}
答案 0 :(得分:0)
您正在正确执行所有操作,但必须将n1 - i
添加到inv
的{{1}}个实例。
背后的原因如下。当你从“右”部分取一个数字时,它低于“左”部分中尚未被采用的任何数字,因此这些对形成反转。 “左”部分中未被捕获的项目数是m - i
[实际数组中的最后一个数字。 INT_MAX存储在索引n1 - 1
] - n1
[当前未获取项目] + i
[因为索引包含],这简化为1
。
另请注意,反转次数可以高达n1 - i
,其中O(n ^ 2)
是数组的大小,因此您可能希望将反转次数存储为{{1}变量。
代码的最终版本:
n