简体   繁体   English

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

[英]Counting the number of inversions in a given array

I tried to solve this problem using merge sort but there is something wrong with my solution.我尝试使用归并排序来解决这个问题,但我的解决方案有问题。 I checked number of inversions while merging the array.我在合并数组时检查了反转次数。 Can someone help me find the issue?有人可以帮我找到问题吗?

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

You are doing everything correctly, except that you have to add n1 - i to inv instad of m - i .你做的一切都是正确的,除了你必须将n1 - i添加到m - i inv instad 。

The reasoning behind that is the following.其背后的原因如下。 When you take a number from the "right" part, it is lower than any number in the "left" part that hasn't been taken yet, and thus such pairs form inversions.当您从“右”部分取一个数字时,它比“左”部分中尚未被取的任何数字都低,因此这些对形成了倒置。 The number of untaken items from "left" part is n1 - 1 [last number from actual array. “左”部分未取出的项目数为n1 - 1 [实际数组中的最后一个数字。 INT_MAX is stored at index n1 ] - i [current untaken item] + 1 [because the indices are inclusive], which simplifies to n1 - i . INT_MAX 存储在索引n1 ] - i [当前未采取的项目] + 1 [因为索引包含在内],简化为n1 - i

Please also note that the number of inversions can be as high as O(n ^ 2) , where n is the size of the array, so you might want to store the number of inversions in a long long variable.另请注意,反转次数可以高达O(n ^ 2) ,其中n是数组的大小,因此您可能希望将反转次数存储在long long变量中。

The final version of the code:代码的最终版本:

int 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 += n1 - i;
        }
    }
    return inv;
}

int mergeSort(int arr[], int l, int r) {
    int inv=0;
    if (l < r) {
        int m = l+(r-l)/2;
        inv += mergeSort(arr, l, m);
        inv += mergeSort(arr, m+1, r);
        inv += merge(arr, l, m, r);
    }
    return inv;
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM