需要帮助找出我在这个反转算法中做错了什么(基于合并排序)
Need help on figuring out what I did wrong in this Inversions algorithm (based on merge sort)
目标是在整数数组中找到反转的数量。例如
给定 : (1,3,5,2,4,6)
反转是:(3,2)、(5,4)、(5,2)。
也就是说,总共三次反转。O(n^2) 解决方案需要两个 for 循环,但对于大型输入数组来说需要太长时间。由于合并排序需要 O(n(log(n))) 时间,因此在这种情况下实现它是有意义的。
通过分而治之的方法,我们可以实现O(n(log(n)))。解决方案是取反转的总和。反转如下(对于大小为"n"的输入数组):
左反转,如果 i,j <= n/2
右反转,如果 i,j> n/2
拆分反转,如果 i <= n/2
注意:拆分反转是在 arr[i]> arr[j] 和 i
基于上述主张,这是我编写的以下算法(其中我首先编写了合并排序的算法,然后相应地对其进行了调整以返回反转的数量),我获得了错误的输出。我无法弄清楚我哪里出错了。
(如有需要,请询问其他信息。我已经坚持了一段时间了)。
#include<iostream>
#include<vector>
using namespace std;
int merge(vector <int> & arr, int l, int m , int r)
{
int i,j,k;
int count = 0;
int n1, n2;
n1=m-l+1;
n2=r-m;
//temporary arrays to store the elements.
int L[n1];
int R[n2];
for (int i = 0; i < n1; ++i)
{
L[i]=arr[l+i];
}
for (int j = 0; j < n2; ++j)
{
R[j]=arr[m+1+j];
}
i=0;
j=0;
k=l;
while(i<n1 && j<n2)
{
if (L[i]<R[j])
{
arr[k]=L[i];
i++;
}
else
{
arr[k]=R[j];
j++;
count=count+(m-i);
}
k++;
}
while(i<n1)
{
arr[k]=L[i];
i++;
k++;
}
while(j<n2)
{
arr[k]=R[j];
j++;
k++;
}
return count;
}
int mergeSort(vector <int> & arr, int l, int r)
{
int m;
int count=0;
/*
if (l<r)
{
m=l+(r-l)/2;
mergeSort(arr, l, m);//used to recursively sort the left half of the array
mergeSort(arr,m+1,r);//used to recursively sort the right half of the array
merge(arr,l,m,r);//merges both arrays together.
}
*/
if(l<r)
{
m = (l + r) / 2;
count =
(mergeSort(arr, l, m) +
mergeSort(arr, m+1, r) +
merge(arr, l, m, r));
return count;
}
else
return 0;
}
void printArray(vector <int> A, int size)
{
for (int i = 0; i < size; ++i)
{
cout<<A[i]<< " ";
}
cout<<endl;
}
int main()
{
int n;
cin>>n;
//int arr[n];
vector<int> arr(n);
int i;
for (i=0; i<n; i++) {
cin>>arr[i];
}
/*
cout<<"the given array is : "<<endl;
printArray(arr, n);
*/
cout<<"the number of inversions are : "<<endl;
cout<< mergeSort(arr, 0, n - 1) <<endl;
/*
cout<<"the sorted array is : "<<endl;
printArray(arr, n);
*/
return 0;
}
测试用例:
案例-1
输入:
(对于 n = 6)
1 3 5 2 4 6
预期输出: 3
获得的输出: 1
案例-2
输入:
(对于 n = 15)
9 12 3 1 6 8 2 5 14 13 11 7 10 4 0
预期输出: 56
获得的输出: 125
问题在于计算我们在每一步中获得的反转次数。让我们来看看合并:我们有两个数组 L 和 R,在每次迭代中,我们查看每个数组中的第一个数字(因为它们已经排序):
1). L[i] <= R[j].这意味着 L[i] 不会用 R 中的一些剩余元素创建新的反转。
2). L[i]> R[J].这意味着 R[j] 将与 L[i], L[i + 1], L[i + 2], ..., L[n1 - 1] 产生反转。从我所看到的,您的错误在于计数计算。您添加 (m - i) 而不是 (n1 - i)。我看到的另一个错误是计数类型。如果你假设大小很大(~10^5),你需要一些更大的类型来存储你的值。
希望这有所帮助。
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- .h 和.cpp文件分离时出错,但仅使用 .h 文件时没有错误.我做错了什么?
- 我的C++线程做错了什么?
- 谁能告诉我我用 getline 做错了什么 (cpp) 格式
- 没有输出的合并排序我做错了什么?
- 我正在尝试使用 while 循环从字符串中删除字母,直到没有字母。我在这里做错了什么?
- 在C++中使用 AKS 素数测试计算双胞胎素数 我做错了什么?
- 我一直试图弄清楚我在这个链表程序中做错了什么
- 我正在尝试学习如何在 c++ 中传递指针,但出现错误:没有用于调用"test"的匹配函数。我做错了什么?
- FFMPEG,C++,内存泄漏,我做错了什么?
- 我做错了什么?反向字符串 C++
- 我在这个课上做错了什么?
- 创建整数的 2D 数组,该数组将使用两个函数用随机数填充矩阵.我做错了什么?
- 在不使用内置库函数的情况下添加字符串,我做错了什么?
- 我做错了什么?GetDiskFreeSpaceExA的功能根本不起作用
- 我在查找和字符串上做错了什么?
- 我正在尝试用 c++ 制作一个日志记录框架,但信息没有传递给记录器的子组件,我做错了什么?
- 我在尝试将多个值push_back向量时出错。我做错了什么?
- 插入排序:我做错了什么?