在数组中查找重复的元素

时间:2011-02-08 21:49:48

标签: arrays algorithm

考虑INT正数的数组:

    {1,3,6,4,7,6,9,2,6,6,6,6,8}

给定:只重复一个数字,用有效的算法返回数字和位置。

有效算法的任何想法?

7 个答案:

答案 0 :(得分:4)

一种可能的解决方案是维护外部哈希映射。迭代数组,并将找到的值的索引放入哈希映射中。完成后,您现在知道哪个数字是重复的,以及找到它的位置的索引。

答案 1 :(得分:1)

在采访中,我猜你有机会询问这个问题,例如,有多少数字?什么范围的数字?你可以说最佳算法可能会有所改变。

这让您有机会展示如何解决问题。

如果数组中的整数范围足够小,那么你可以创建另一个数组来保持每个整数被找到的次数的计数,然后线性地通过数组累积出现次数,当你到达出现次数时停止两个。

答案 2 :(得分:0)

Hash会在这里做得很好。每次都要添加数字,每次检查数字是否已经存在。

答案 3 :(得分:0)

嗯,可能有一些技巧(通常是)。但就在袖口之外,您应该能够对列表进行排序(O(nlogn))。然后它只是找到一个与下一个相同的数字(线性搜索 - O(n))。当然,您必须将其排序为值元组和原始索引,因此您可以返回正在查找的索引。但重点是,算法的上限应该是O(nlogn)

如果您只是逐行浏览列表,则可以获取每个索引,然后在其后搜索列表的其余部分以查找匹配的索引。我认为这大致相当于冒泡排序中的工作,所以它可能是O(n^2),但只是一个简单的。

我真的很讨厌把问题作为面试问题。它们有点像视觉幻觉:要么你看到了,要么你没看到,但如果你没有看到这个伎俩,它对你没有任何坏处。

答案 4 :(得分:0)

我试试这个:

  1. 必须查看所有列表中的elms(=>循环遍历列表)
  2. 在重复的榆树知道之前,存储elm =>哈希/字典中的位置/索引
  3. 一旦发现重复元素的第二次出现,将其第一个位置(来自散列)和当前位置存储在结果数组中
  4. 将列表的其他elms与重复的elm进行比较,将找到的位置追加到结果数组
  5. 代码:

    Function locRep( aSrc )
      ' to find repeated elm quickly
      Dim dicElms : Set dicElms = CreateObject( "Scripting.Dictionary" )
      ' to store the locations
      Dim aLocs   : aLocs       = Array()
      ' once found, simple comparison is enough
      Dim vRepElm : vRepElm     = Empty
      Dim nIdx
      For nIdx = 0 To UBound( aSrc )
          If vRepElm = aSrc( nIdx ) Then ' repeated elm known, just store location
             ReDim Preserve aLocs( UBound( aLocs ) + 1 )
             aLocs( UBound( aLocs ) ) = nIdx
          Else ' repeated elm not known
             If dicElms.Exists( aSrc( nIdx ) ) Then ' found it
                vRepElm = aSrc( nIdx )
                ReDim aLocs( UBound( aLocs ) + 2 )
                ' location of first occurrence
                aLocs( UBound( aLocs ) - 1 ) = dicElms( aSrc( nIdx ) )
                ' location of this occurrence
                aLocs( UBound( aLocs )     ) = nIdx
             Else
                ' location of first occurrence
                dicElms( aSrc( nIdx ) ) = nIdx
             End If
          End If
      Next
      locRep = aLocs
    End Function
    

    试运行:

    -------------------------------------------------
         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
    Src: 1 3 6 4 7 6 9 2 6 6 6 6 8
    Res: 2 5 8 9 10 11
    ok
    
    Src:
    Res:
    ok
    
    Src: 1 2 3
    Res:
    ok
    
    Src: 1 1 2 3 4 5 6
    Res: 0 1
    ok
    
    Src: 1 2 3 4 5 6 6
    Res: 5 6
    ok
    
    =================================================
    

答案 5 :(得分:0)

using namespace std;
list<int> find_duplicate_idx(const vector<int>& A)
{
hash_map<int, int> X;
list<int> idx;
for ( int i = 0; i < A.size(); ++ i ) {
  hash_map<int, int>::iterator it = X.find(A[i]);
  if ( it != X.end() ) {
    idx.push_back(it->second);
    idx.push_back(i);
    for ( int j = i + 1; j < A.size(); ++j )
      if ( A[j] == A[i] )
        idx.push_back(j);  
    return idx;
  }
  X[A[i]] = i;
}
return idx;
}

这是我朋友提供的解决方案。感谢来自mitbbs.com的SETI

答案 6 :(得分:0)

使用hash-map解决它:

private int getRepeatedElementIndex(int[] arr) {

    Map<Integer, Integer> map = new HashMap();
    // find the duplicate element in an array
    for (int i = 0; i < arr.length; i++) {
        if(map.containsKey(arr[i])) {
            return i;
        } else {
            map.put(arr[i], i);
        }
    }
    throw new RuntimeException("No repeated element found");
}

时间复杂度:O(n)

空间复杂度:O(n)