Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在具有单个循环的数组中查找重复项_C#_Arrays_Algorithm - Fatal编程技术网

C# 在具有单个循环的数组中查找重复项

C# 在具有单个循环的数组中查找重复项,c#,arrays,algorithm,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) {

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

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");
    }       
}
int[]Arr={9,5,6,3,8,2,5,1,7,4};
int[]Arr2={0,0,0,0,0,0,0,0,0,0};
对于(int i=0;i
使用任何
实现,比如
哈希集
,例如

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);
这是最新的

如果没有额外的空间,这个问题不能严格线性地解决

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

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

  • 使用LINQ获取所有副本的最快方法是:

    var duplicates = Arr.GroupBy(s => s).SelectMany(d => d.Skip(1));
    
    这将返回
    Arr
    中所有重复元素的
    IEnumerable
    ,您可以使用以下检查来包含是否存在任何重复项:

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

    如果只有数组
    a[]
    包含范围
    [0,n-1]
    {如您的问题所示}
    中的数字,并且n不是非常大,以避免整数范围溢出,那么这将起作用

    for(i=0;i<n;i++)
    {
        if(a[a[i]%n]>=n)
             **duplicate is a[i]** !
        else   
        a[a[i]%n]+=n;
    
    }
    
    (i=0;i=n)的
    
    **重复是一个[i]**!
    其他的
    a[a[i]%n]+=n;
    }
    
    时间复杂度:O(N)

    空间复杂性:O(1)

    使用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);
    

    由于您有这种情况:

    问题是存在和未排序的数组,最大值应小于长度。

    另外,假设只有
    正数
    数字,在您的示例中适用

    这可以使用
    O(n)
    时间和
    O(1)
    空间来完成,而无需使用任何LINQ、字典、哈希等

    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");
    }
    
    int[]arr={9,5,6,3,8,2,5,1,7,4};
    对于(int i=0;i=0)
    arr[Math.Abs(arr[i])]=-arr[Math.Abs(arr[i]);
    其他的
    Console.WriteLine(“找到重复项”+Math.Abs(arr[i]).ToString()+“\n”);
    }
    
    使用集合而不是第二个数组。在添加到集合之前,请检查集合是否包含该元素-如果包含,则有一个副本。或者您可以只检查
    Add
    中的返回值-如果它是
    false
    ,元素已经存在。您能给我一个例子吗?它与当前的方法有什么不同?以前从未使用过C,但设置了≠ 数组,在大多数编程语言中,一个集合意味着一个HashSet,在它的每个元素上强制一个唯一的约束。然后你的前提条件确保了一定有重复。考虑长度为2的数组,它只能是{ 1, 1 }。这是相同的方法吗?是的,你的方法使用散列。但我建议保留一个位数组而不是int数组,以减少内存开销。@Muneeb Zulfiqar:它可以处理任意整数,比如“int[]Arr={5559,-2225,-56,23,-56};”@Mohit Jain:No;这个解决方案适用于任意整数,比如“int[]Arr={5559,-2225,-56,23,-56};”,这就是为什么我不想使用bitarray@Dmitry是的,你是对的。我说的不是实现,而是散列的概念。这个想法基本上是一样的。我更喜欢您的整数集方式,这样我的解决方案就可以在完整的整数范围内运行。使用哈希或BST实现的集合。对于这样小的内存,当您不使用标准功能并自行实现时(可能需要学习,或者数组边界已知),我建议首选位集合。条件是只循环一次。如何在单个循环中进行排序和比较?@MuneebZulfiqar
    foreach(Arr.OrderBy(s=>s)中的变量a)
    OrderBy此循环多次sir@MuneebZulfiqar这个答案的目的是向你们表明,并不是我们想要的一切都能做到。如果没有额外的空间,这个问题不可能在一个循环中解决,这应该给你一个提示,你走在正确的轨道上。@amit我也有同样的想法,我只是需要一些专家的意见:)Linq不能使用。因为它会违反使用单循环的条件。@MuneebZulfiqar你是对的,
    GroupBy
    实际上循环三次只是为了排序。:)
    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");
    }