排序数组算法 - 重复值

时间:2014-12-22 18:19:45

标签: sorting array-algorithms

我有一个带有重复值的整数数组大小N,我不知道值的范围。 我在这个数组中有n / logn不同的值,其余的都是重复的。

有没有办法按时间复杂度O(n)和内存复杂度O(n / logn)对其进行排序?

4 个答案:

答案 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))空间

最后,通过根据哈希映射中记录的重复数字复制元素,将有序数组扩展为最终结果。