计算给定数组中的反转次数

时间:2017-09-17 14:44:42

标签: arrays algorithm data-structures mergesort

我尝试使用合并排序解决此问题,但我的解决方案有问题。我在合并数组时检查了反转次数。 有人可以帮我找到问题吗?

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;
} 

1 个答案:

答案 0 :(得分:0)

您正在正确执行所有操作,但必须将n1 - i添加到inv的{​​{1}}个实例。

背后的原因如下。当你从“右”部分取一个数字时,它低于“左”部分中尚未被采用的任何数字,因此这些对形成反转。 “左”部分中未被捕获的项目数是m - i [实际数组中的最后一个数字。 INT_MAX存储在索引n1 - 1] - n1 [当前未获取项目] + i [因为索引包含],这简化为1

另请注意,反转次数可以高达n1 - i,其中O(n ^ 2)是数组的大小,因此您可能希望将反转次数存储为{{1}变量。

代码的最终版本:

n