算法:查找出现两次的元素

时间:2013-01-03 11:02:03

标签: algorithm

输入:未排序的整数数组A[1..n],只有O(d) :(d < < n)个不同的元素。

输出:所有出现两次的元素。

要求两种算法,一种是O(Nd),另一种是O(Nlogd)。最大数量可能非常大,因此计算频率的大小为n的数组可能不是一个好主意。有什么想法吗?

澄清一下,“只有O(d) :(d < < n)个不同的元素”意味着所有其他元素(不是那些O(d)元素)出现两次或更多。

3 个答案:

答案 0 :(得分:1)

O(nd)基本上迭代所有可能的元素(O(d))并计算它重复的次数。每次迭代都是O(n)

O(nlogd)构建一个histogram map:int->int),它计算每个元素在一次迭代中出现在列表中的次数。地图为balanced Binary Search Tree,以确保O(nlogd)。请注意,如果您使用hash map而不是树,则可以将其增加到O(n)平均大小写(但O(nd)最差情况)

Psuedo代码 - O(nlogd):

map <- new tree map
for each element x in list:
 if x is in map:
     map.put(x,map.get(x)+1)
 else:
     map.put(x,1)
for each (key,value) in map:
  if value == 2:
     print key

答案 1 :(得分:0)

对数组进行排序。 O(nlogn) 扫描数组以找到仅出现两次的元素.O(n)

重复元素将并排。

为O(n)+ O(nlogn)。

答案 2 :(得分:0)

溶液一O(N * d)

  1. 查找数组中其值等于A [0]的所有元素,计算 数。如果数字== 2,请将其添加到答案中。最后,擦除所有 从阵列中选择的元素。
  2. 擦除所有相同的值元素会导致O(N)复杂性,而这一点 step1应该做d次,所以复杂度是O(N * d)。
  3. 解决方案二O(N * logd)

    使用平衡树计算所有值的频率。因为只有d dinstinct值,所以树的大小只有d,并且它上面的所有操作都将被记录。我们将所有元素插入到树中,并计算树中节点的频率,总复杂度为O(N * logd)。

    C++ code:
    
    vector<long long> solve()
    {
        vector<long long> ans;
        map<long long, int> cnt;
        for(int i = 0; i < n; ++i)
            cnt[a[i]] += 1; // O(logd)
        for(map<long long, int>::iterator it = cnt.begin(); it != cnt.end(); ++it)
            if(it -> second == 2) ans.push_back(it -> first);
        return ans;
    }