在最短的时间内从此列表中查找重复元素

时间:2018-04-12 15:08:23

标签: java data-structures

我正在接受采访,并且有一个问题是有一个List,其中包含整数。 List的大小为100万条记录,所有记录都是整数。

我的任务是找到具有最佳运行时的重复项。我无法回答正确的答案,因为我告诉他我可以通过使用两个循环来实现在如此大的列表中找到重复数字的相同但是这可以通过最佳运行时尽快完成吗? / p>

3 个答案:

答案 0 :(得分:1)

您需要迭代整数并跟踪您已经看过的整数。为此,您需要一个高效的数据结构,它具有addcontains操作的良好运行时复杂性。

例如,您可以使用has set来跟踪看到的整数:

    Set<Integer> duplicateIntegers = new LinkedHashSet<>();
    Set<Integer> seenIntegers = new HashSet<>();

    for (Integer integer : integers) {
        if (!seenIntegers.add(integer)){
            duplicateIntegers.add(integer);
        }
    }

这里我们迭代N个整数,将其添加到seenIntegers并检查当前是否已经存在整数,这是分摊的O(1)。因此,最后时间为O(N)O(N)为额外空间。

O(1)的{​​{1}}已摊销(请参阅here实际含义)。由于我们处理整数并且它们不是那么多,我们可以使用更多的额外空间来实现诚实至善[{1}}。我们只需要2 ^ 32位, 512Mb。为此,我们可以使用HashSet.add。实际上,两个O(1)因为我们需要2 ^ 32位但BitSet只能用int的最大值初始化,即2 ^ 31-1。

BitSet

这也是BitSet,但基于诚实 - 未摊还 BitSet seenNonNegativeIntegers = new BitSet(Integer.MAX_VALUE); BitSet seenNegativeIntegers = new BitSet(Integer.MAX_VALUE); Set<Integer> duplicateIntegers = new LinkedHashSet<>(); for (Integer integer : integers) { int i = integer.intValue(); if (i >= 0) { if (seenNonNegativeIntegers.get(i)) { duplicateIntegers.add(integer); } seenNonNegativeIntegers.set(i); } else if (i < 0) { int index = -(i + 1); if (seenNegativeIntegers.get(index)) { duplicateIntegers.add(integer); } seenNegativeIntegers.set(index); } } 。从理论上讲,从运行时复杂性的角度来看,这必须是最优的解决方案。实际上,O(N)可能仍然较慢,因为我们必须O(1)HashSet而不是get

在接受采访时,我可能会提出第一个解决方案,提到第二个解决方案并讨论运行时复杂性与额外空间要求。

答案 1 :(得分:0)

最简单的解决方案是使用HasMap,unordered_set。

def find_duplicates(a): used = set() yielded = set() for x in a: if x in used and x not in yielded: yield x yielded.add(x) used.add(x)

答案 2 :(得分:0)

public class CountArrayList extends ArrayList<YourType>{

       private HashMap<YourType, Integer> count = new HashMap<>();

       @Override
       public boolean add(YourType element){
             Integer i = count.get(element);
             count.put(element, i == null ? 1 : ++i);
             return super.add(element);
       }

       public int getItemCount(YourType element){
             return count.get(element) == null ? 0 : count.get(element);
       }
}

此类未完成,您应该覆盖remove和其他方法,例如add method to update count