如何在O(n)时间和O(1)空间复杂度中找到数组中的重复数

时间:2011-09-10 10:02:44

标签: algorithm data-structures

如何在O(n)时间和O(1)复杂度中找到数组中的重复数? 例如 数组2,1,4,3,3,10 输出为3

编辑: 我尝试了以下方式。 我发现如果没有奇怪的重复,那么我们可以通过xor来实现结果。所以我想让奇怪的元素不重复甚至没有,每个均匀地重复no到odd.but为此我需要从O(n)中的输入数组中找出唯一的元素数组但是找不到方法。

8 个答案:

答案 0 :(得分:3)

在不了解数组中可能的值的情况下,您无法了解。

对于O(1)空间要求,最快的方法是对数组进行排序,使其至少为O(n * log(n))。

答案 1 :(得分:3)

假设数组中的数字值有一个上升界限(我使用的所有编程语言中的所有内置整数类型就是这种情况 - 例如,假设它们是32 -bit整数)有一个使用常量空间的解决方案:

  1. 创建一个包含N个元素的数组,其中N是输入数组中整数值的上限,并将所有元素初始化为0false或某些等价物。我将其称为 lookup 数组。
  2. 循环输入数组,并使用每个数字索引到查找数组中。如果找到的值是1true(等),则输入数组中的当前数字是重复的。
  3. 否则,请将查找数组中的相应值设置为1true,以便记住我们已看到此特定输入数字。
  4. 技术上,这是O(n)时间和O(1)空间,并且它不会破坏输入数组。实际上,你需要事情来实现这样的程序实际运行(例如,如果在输入中讨论64位整数,那就不可能了。)

答案 2 :(得分:1)

使用位操作...在一个循环中遍历列表。

  1. 通过从i移位值来检查掩码是否为1。
  2. 如果是这样,打印出重复值i。
  3. 如果未设置该值,请将其设置。
  4. *如果您只想显示一次重复值,请添加另一个整数节目并设置其位,如下例所示。

    **这是在java中,我不确定我们是否会访问它,但您可能还想使用Integer.MAX_VALUE添加检查。

        public static void repeated( int[] vals ) {
            int mask = 0;
            int show = 0;
            for( int i : vals ) {
                // get bit in mask
                if( (( mask >> i ) & 1) == 1 &&
                    (( show >> i ) & 1) == 0 )
                {
                    System.out.println( "\n\tfound: " + i );
                    show = show | (1 << i);
                }
    
                // set mask if not found
                else
                {
                    mask = mask | (1 << i);
                    System.out.println( "new: " + i );
                }
    
                System.out.println( "mask: " + mask );
            }
        }
    

答案 3 :(得分:0)

如果不知道有关输入数组的任何限制规则,这是不可能的,要么内存复杂性会对输入大小有所依赖,要么时间复杂度会更高。

上面的2个答案实际上是接近你所要求的最佳答案,一个人的权衡是第二次权衡在记忆中的时间,但你不能在O(n)时间和O(1)中运行)一些未知的输入阵列的复杂性。

答案 4 :(得分:0)

我也遇到了这个问题,我的解决方案是使用hashMap .. python版本如下:

  def findRepeatNumber(lists):
      hashMap = {}
      for i in xrange(len(lists)):
          if lists[i] in hashMap:
              return lists[i]
          else: 
              hashMap[lists[i]]=i+1
      return

答案 5 :(得分:0)

只有拥有特定数据才有可能。例如,所有数字都是小范围的。然后,您可以在源阵列中存储重复信息,而不会影响整个扫描和分析过程。

简化示例:您知道所有数字都小于100,那么您可以使用额外的零标记数字的重复计数,例如,当9发生两次时,将900替换为9而不是9。

NumMax-NumMin很容易

http://www.geeksforgeeks.org/find-the-maximum-repeating-number-in-ok-time/

答案 6 :(得分:-1)

public static string RepeatedNumber()
    {
        int[] input = {66, 23, 34, 0, 5, 4};
        int[] indexer = {0,0,0,0,0,0}
        var found = 0;
        for (int i = 0; i < input.Length; i++)
        {
            var toFind = input[i];
            for (int j = 0; j < input.Length; j++)
            {
                if (input[j] == toFind && (indexer[j] == 1))
                {
                    found = input[j];
                }
                else if (input[j] == toFind)
                {
                    indexer[j] = 1;
                }
            }

        }


    return $"most repeated item in the array is {found}";

}

答案 7 :(得分:-4)

你可以这样做

#include<iostream.h>
#include<conio.h>
#include<stdio.h>
void main ()
{
    clrscr();
    int array[5],rep=0;
    for(int i=1; i<=5; i++)
    {
        cout<<"enter elements"<<endl;
        cin>>array[i];
    }
    for(i=1; i<=5; i++)
    {
        if(array[i]==array[i+1])
        {
            rep=array[i];
        }
    }
    cout<<" repeat value is"<<rep;
    getch();
}