使用单循环在Array中查找重复项

时间:2014-04-08 07:24:03

标签: c# arrays algorithm

问题是存在和未排序的数组,最大值应小于长度。我必须在数组中找到重复的记录。条件是只使用一次循环。这是我迄今取得的成就。我想知道是否有任何其他方法可以实现这一点。

int[] Arr = { 9, 5, 6, 3, 8, 2, 5, 1, 7, 4 };
int[] Arr2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int i = 0; i < Arr.Length; i++)
{
    if (Arr2[Arr[i]] == 0)
    {
        Arr2[Arr[i]] = Arr[i];
    }
    else
    {
        Console.WriteLine("duclicate found");
    }       
}

6 个答案:

答案 0 :(得分:9)

使用任何Set实施,例如HashSet<T>,例如

HashSet<int> hs = new HashSet<int>();
int[] Arr = { 9, 5, 6, 3, 8, 2, 5, 1, 7, 4 };

foreach (item in Arr) 
  if (hs.Contains(item)) {
    Console.WriteLine("duplicate found");
    // break; // <- uncomment this if you want one message only
  }
  else 
    hs.Add(item);

修改:,因为hs.Add返回bool,可以提供更短,更高效的代码:

HashSet<int> hs = new HashSet<int>();
int[] Arr = { 9, 5, 6, 3, 8, 2, 5, 1, 7, 4 };

foreach (item in Arr) 
  if (!hs.Add(item)) {
    Console.WriteLine("duplicate found");
    // break; // <- uncomment this if you want one message only
  }

答案 1 :(得分:3)

因为你有这个条件:

The question is there is and unsorted array and the maximum value should be smaller than the length.

还假设只有positive个数字,在您的示例中适用

这可以使用O(n)时间和O(1)空间来完成,而无需使用任何LINQ,Dictionary,Hashing等。

int[] arr = { 9, 5, 6, 3, 8, 2, 5, 1, 7, 4 };
for (int i = 0; i < arr.Length; i++)
{
     if (arr[Math.Abs(arr[i])] >= 0)
         arr[Math.Abs(arr[i])] = -arr[Math.Abs(arr[i])];
     else
         Console.WriteLine("Duplicate found " + Math.Abs(arr[i]).ToString() + "\n");
}

答案 2 :(得分:2)

这是Element Distinctness Problem

如果没有额外的空间,这个问题就无法严格线性地解决。

解决问题的两种常用方法是:

  1. 使用HashSet - 在迭代时填充它,如果找到匹配则中止 - 平均O(n)时间和O(n)空间
  2. 排序和迭代,在对数组进行排序后,重复项将彼此相邻并易于检测。这是O(nlogn)时间和非常少的额外空间。

答案 3 :(得分:0)

使用LINQ获取所有重复项的最快方法是:

var duplicates = Arr.GroupBy(s => s).SelectMany(d => d.Skip(1));

这将返回IEnumerable中所有重复元素的Arr,您可以使用以下检查来包含是否存在重复项:

if (duplicates.Any())
{
    // We have a duplicate!
}

答案 4 :(得分:0)

如果只有数组a[]包含范围[0,n-1] {as in your question}中的数字且n不是很大以避免整数范围溢出,这将有效。

for(i=0;i<n;i++)
{
    if(a[a[i]%n]>=n)
         **duplicate is a[i]** !
    else   
    a[a[i]%n]+=n;

}

时间复杂度:O(N)
空间复杂度:O(1)

答案 5 :(得分:0)

使用LINQ

尝试此代码
    int[] listOfItems = new[] { 4, 2, 3, 1, 6, 4, 3 };
var duplicates = listOfItems
    .GroupBy(i => i)
    .Where(g => g.Count() > 1)
    .Select(g => g.Key);
foreach (var d in duplicates)
    Console.WriteLine("The duplicate is "+d);