我有一个带有重复值的整数数组大小N,我不知道值的范围。 我在这个数组中有n / logn不同的值,其余的都是重复的。
有没有办法按时间复杂度O(n)和内存复杂度O(n / logn)对其进行排序?
答案 0 :(得分:0)
可能你可以使用这个:
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
int main()
{
int n=7;
int v[]={4,1,2,3,2,4,1}; // initial array
map<int,int>mp;
vector<int>uni;
for(int i=0;i<n;i++)
if(++mp[v[i]]==1) // counting instance of unique values
uni.push_back(v[i]); // unique value
sort(uni.begin(),uni.end()); // sorting : O ((n / logn) * logn) = O(n)
int cur=0;
for(int i=0;i<uni.size();i++)
{
int cnt=mp[uni[i]];
while(cnt) // Adding duplicate values
{
v[cur++]=uni[i];
cnt--;
}
}
for(int i=0;i<n;i++) // Printing final sorted array
cout<<v[i]<<" ";
cout<<"\n";
return 0;
}
此处uni
数组保留唯一值,即最大n / logn
值
然后我们使用了具有时间复杂度sort()
的stl O (n * logn)
函数
在这里总元素n = n / logn
。复杂性为O ((n / logn) * logn) = O(n)
。
所以我们看到,上面的方法适用于O(n)
内存O(n * logn)
的复杂性。
此处map<>
用于计算每个不同值的显示次数。
答案 1 :(得分:0)
只需保留键值对
for(i=0;i<n;i++)
{
int key = a[i];
// if value is in map increase vale of this key
// else add key with value 1
}
现在使用合并排序将此地图数据写入输出数组 希望这能解决你的问题。
答案 2 :(得分:-1)
冒泡排序需要O(n ^ 2)时间,并且几乎不需要执行任何内存(除了存储原始数组) - 请参阅http://rosettacode.org/wiki/Sorting_algorithms/Bubble_sort。快速排序要快得多 - 请参阅http://rosettacode.org/wiki/Quick_Sort
重复不会影响其中任何一种算法
答案 3 :(得分:-1)
Mergesort,例如,O(n * lg(n))时间算法,具有O(n)空间复杂度。
您可以使用哈希映射将n / lg(n)个唯一项提取到它们自己的数组中,并记下每个项发生的次数;这是(预期的)O(n)时间和O(n / lg(n))空间。现在,您可以在新阵列上运行Mergesort,即:
O(x * lg(x))时间,x = n / lg(n)==
O(n / lg(n)* lg(n / lg(n)))==
O(n / lg(n)* [lg(n) - lg(lg(n))])==
O(n - n * lg(lg(n))/ lg(n))
&lt; = O(n)时间
和
O(x)空间,x = n / lg(n)==
O(n / lg(n))空间
最后,通过根据哈希映射中记录的重复数字复制元素,将有序数组扩展为最终结果。