在常量空间和O(n)时间内查找重复条目的算法

时间:2011-11-24 16:43:15

标签: c++ algorithm

给定一个N整数数组,使得只重复一个整数。在O(n)时间和常量空间中找到重复的整数。整数值或N

的值没有范围

例如,给出一个由6个整数组成的数组,如23 45 67 87 23 47.答案是23 (我希望这涵盖含糊不清的部分)

我在网上搜索但无法找到任何这样的问题,其中整数范围没有修复。 另外here是一个回答类似问题的例子,但是在这里他创建了一个在C ++中具有最高整数值的哈希表。但是cpp不允许这样创建一个包含2 ^ 64元素的数组(在64位计算机)。

对不起,我在数组不可变之前没有提到它

8 个答案:

答案 0 :(得分:8)

Jun Tarui shown任何使用O(log n)空间的重复查找器都需要至少Ω(log n / log log n)通过,这超过了线性时间。即即使你允许对数空间,你的问题也证明是无法解决的。

Gopalan和Radhakrishnan有一个有趣的algorithm,它在输入和O((log n)^ 3)空间的一次传递中找到重复,这听起来像是你事先最好的选择。

Radix sort具有时间复杂度O(kn),其中k> 0。 log_2 n经常被视为常数,尽管是一个大常数。您无法在常量空间中实现基数排序,但您可以重用输入数据的空间。

如果你假设数字本身的特征,有一些数字技巧。如果几乎存在1和n之间的所有数字,则只需将它们相加并减去n(n + 1)/ 2。如果所有数字都是素数,你可以通过忽略除法的运行时间来作弊。

另外,在比较排序中有一个众所周知的Ω下限(log_2(n!)),这表明谷歌可能会帮助您找到简单问题的下限,例如查找重复项。

答案 1 :(得分:5)

如果数组未排序,则只能在O(nlogn)

中进行排序

可以找到一些方法here

答案 2 :(得分:4)

如果整数范围有界,则可以在O( n )时间内执行counting sort变体。空间复杂度为O( k ),其中 k 是整数(*)的上限,但这是一个常数,所以它是O(1)。

如果整数的范围是无界的,那么我认为没有办法做到这一点,但我不是复杂难题的专家。

(*)它是O(k),因为每个整数的出现次数也有一个常数上限,即2。

答案 3 :(得分:3)

答案 4 :(得分:2)

最接近O(N)的方法可能是传统的哈希表,其中哈希条目只是数字,用作键。在首先检查它是否已经在表中之后,您将遍历列表,在哈希表中插入每个条目。

然而,严格来说不是O(N),因为当表填满时散列搜索/插入变慢。就存储而言,对于大型列表来说这将是昂贵的 - 至少是数字数量的3倍,可能是10-20倍。

答案 5 :(得分:2)

正如其他人已经提到的那样,我认为没有办法在O(n)中做到这一点。

但是,您可以使用Bloom Filter尝试概率方法。如果你幸运,它会给你O(n)。

答案 6 :(得分:0)

由于不允许额外的空间,如果没有比较就无法做到这一点。comparison sort时间复杂度的下界概念可用于证明原始形式的问题不能成为问题。在最坏的情况下解决了O(n)。

答案 7 :(得分:0)

我们也可以在线性时间o(n)中进行

public class DuplicateInOnePass {

    public static  void duplicate()

   {
        int [] ar={6,7,8,8,7,9,9,10};
        Arrays.sort(ar);
        for (int i =0 ; i <ar.length-1; i++)
        {


            if (ar[i]==ar[i+1])
                System.out.println("Uniqie Elements are" +ar[i]);

        }  

    }

    public static void main(String[] args) {
        duplicate();
    }
}