用无限输入检测重复

时间:2010-02-17 09:39:21

标签: language-agnostic data-structures repeat infinite-sequence

在无限的整数序列中找到重复的最佳方法是什么?

即。如果在无限序列中数字'5'出现两次,那么我们将第一次返回'false'而第二次返回'true'。

最后我们需要的是一个函数,如果整数出现在前面,则返回'true',如果函数第一次收到整数,则返回'false'。

如果有两个解决方案,一个是空间方式,第二个是时间方式,那么两个都提到。 我会在答案中写下我的解决方案,但我认为这不是最佳解决方案。

编辑:请不要假设琐碎的情况(即没有重复,不断上升的序列)。我感兴趣的是如何减少非平凡情况的空间复杂性(重复的随机数)。

5 个答案:

答案 0 :(得分:1)

我会使用以下方法:

使用哈希表作为数据结构。对于读取的每个数字,将其存储在数据结构中。如果在您发现重复之前已经存储了它。

如果n是从开始到重复的序列中元素的数量,那么这只需要O(n)时间和空间。时间复杂度是最佳的,因为您需要至少读取输入序列的元素直到重复点。

我们说话的序列有多长(在重复发生之前)?重复甚至可以保证吗?对于极端情况,空间复杂性可能会成为问题。但要改进它,您可能需要了解更多关于序列的结构信息。

更新:如果序列如你所说很长很少重复并且你必须减少空间要求,那么你可以(给出足够的序列结构信息)能够减少空间成本。

作为一个例子:假设您知道您的无限序列通常倾向于返回符合当前目标最小 - 最大数字范围内的数字。然后,您最终将具有已包含在序列中的整个间隔。在这种情况下,您可以通过存储此类间隔而不是其中包含的所有元素来节省空间。

答案 1 :(得分:1)

int值的BitSet(2 ^ 32个数字)将消耗512Mb。如果BitSets不经常分配,足够快并且mem可用,则可能没问题。

替代方案是compressed BitSets,最适合稀疏的BitSet。

答案 2 :(得分:1)

实际上,如果最大值的数量是无限的,则可以对单色位图使用任何无损压缩算法。如果你想象一个像素数量至少与可能值的数量一样多的正方形,你可以将每个值映射到一个像素(有几个像素备用)。然后,您可以将白色表示为出现的像素,将其他像素表示为黑色,如果空间非常宝贵,则可以使用任何压缩算法(这肯定是已经研究过的问题)

您还可以存储块。最坏的情况在空间O(n)中是相同的,但对于最坏的情况,您需要出现的数字恰好在它们之间为1。一旦出现更多数字,存储将减少: 我将编写伪代码,我将使用List,但您总是可以使用不同的结构

List changes // global

boolean addNumber(int number):
  boolean appeared = false
  it = changes.begin()
  while it.hasNext():
    if it.get() < number:
      appeared != appeared
      it = it.next()
    else if it.get() == number:
      if !appeared: return true
      if it.next().get() == number + 1
        it.next().remove() // Join 2 blocks 
      else 
        it.insertAfter(number + 1)  // Insert split and create 2 blocks
      it.remove()
        return false
    else: // it.get() > number
      if appeared: return true
      it.insertBefore(number)
      if it.get() == number + 1:
        it.remove() // Extend next block
      else:
        it.insertBefore(number + 1)  
  }
  return false
}

此代码如下:它存储块列表。对于您添加的每个数字,它会迭代列表,其中包含出现的数字块和未出现的数字块。让我用一个例子来说明;我将添加[)来说明块中的哪些数字,包含第一个数字,最后一个不是。在伪代码中,它被布尔appeared替换。例如,如果你得到5,9,6,8,7(按此顺序),你将在每个函数后有以下序列:

[5,6)

[5,6),[9,10)

[5,7),[9,10)

[5,7),[8,10)

[5,10)

在最后一个值中,您只保留5个数字的块,只有2个。

答案 3 :(得分:0)

返回TRUE

如果序列是无限的,则会重复每个可想到的模式。

如果您想知道的是序列中的第一个位置,那么重复的数字是另一个问题,但是您的问题与您的示例之间存在一些差异。

答案 4 :(得分:0)

嗯,似乎很明显,在任何解决方案中我们都需要保存已经出现的数字,因此在空间方面我们总是具有O(N)的最坏情况,其中N

为了保存已经出现的数字,我会使用哈希表,然后在每次收到新号码时检查它。