[英]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.