从4位整数流中查找中位数的空间使用量下限为什么是“ log n”位?

问题描述

今天,在课程(算法课程)中,教授说,从n个4位整数的流中查找中值的空间使用量的下限(以位为单位)为log n。知道为什么这是真的吗?

解决方法

直觉上,Θ(log n)位足以写出您看到16个可能的4位值中的每一个的次数,然后可以计算出中位数。为什么不能(渐近地)改善这一点的直觉是这样的想法:如果使用较少的位,您甚至不记得看到每个数字多少次了,因此无法始终返回中位数。

以下是我要提出的正式论点的要点。想象一下,我将输入的前一半输入到您的算法中。如果没有足够的内存,您将无法唯一地记住该输入是什么。而且,如果您不记得该输入的内容,那么我可以通过恶意选择数字序列的后半部分来迫使您的算法给出错误的答案。

要对此进行形式化,让我们假设您有一种算法声称使用内存的o(log n)(顺便说一下,log n很少-o)来解决此问题。现在,假设我有一个“足够大”的n = 2k + 1个数字流,每个数字长4位。由于您使用的是o(log n)位内存,并且我选择n为“足够大”,因此可以说您的算法使用的内存严格少于log(n-1)-1 = log( 2k)-1 = 1 +日志k-1 =日志k个内存位。

现在,考虑以下k个选择,以选择要流经算法的4位数字序列。第一个是k个副本0000。第二个是k-1个副本0000,然后是1个副本1111。第三个是k-2个副本0000,然后是2个副本1111。更一般地说,有一个序列对于k + 1种不同选择中的每一种,它们分别具有0000的拷贝数和1111的拷贝数。

现在,通过算法运行所有k + 1个可能的选项。您使用的内存严格少于log k位,因此内存的那些位可能少于2 log k = k个可能的组合。这是一个问题,因为我有k +1个不同的序列。因此,在执行算法时,必须有两个序列使算法的存储器以相同状态结束。假设第一个具有s的副本0000,第二个具有0000的t副本,其中s

请注意,我们仅将流中的k个元素输入到您的算法中,因此我们还有k + 1个剩余元素可供选择。如果我选择它们,以便精确地有0000个k-s副本,而其余s + 1个元素为1111,该怎么办?好吧,在这种情况下,看看会发生什么。

  • 采用s副本0000的原始序列,然后是1111的k-s副本,并通过算法运行它。然后为其提供0000个k-s副本和1111的s + 1个副本。现在,整个流具有0000个k个副本和1111的k + 1个副本,这意味着中位数为1111。
  • 取t> s个副本的原始序列为0000,然后是k-t

但是在这里我们遇到了一个问题。看到输入的前半部分后,算法的状态是相同的,并且我们输入的序列与输入的后半部分相同,因此在上述两种情况下,算法的行为应相同。但这不能,因为正如我们在这里看到的那样,输出应该是不同的。对于任何确定性算法而言,这都是不可能的!

顺便说一句,这种论据风格基于fooling set的思想,它是一组输入,以便任何两个输入都有至少一个可以加后缀的后缀,以区分这两个后缀输入。它与常规语言的Myhill-Nerode theorem有关,您可以将任何具有有限内存的确定性流算法视为DFA,每个内存位组合具有一个状态。