小编典典

简单的面试问题变得更难:给定数字 1..100,找到缺少的数字

all

不久前,我有一次有趣的求职面试经历。这个问题开始很容易:

Q1 : 我们有一个包含数字1, 2, 3, …,的包100。每个数字只出现一次,所以有 100 个数字。现在从袋子里随机抽出一个号码。找到丢失的号码。

当然,我以前听过这个面试问题,所以我很快就回答了:

A1:嗯,数字的总和1 + 2 + 3 + … + N(N+1)(N/2)(参见维基百科:算术级数的总和)。对于N = 100,总和是5050

因此,如果所有数字都出现在包中,则总和将是5050。由于缺少一个数字,因此总和将小于此数字,差值就是那个数字。O(N)所以我们可以在时间和O(1)空间上找到那个缺失的数字。

此时我以为我做得很好,但突然之间问题发生了意想不到的转变:

Q2 : 是的,但是现在如果缺少两个数字,你会怎么做?

我以前从未见过/听说过/考虑过这种变化,所以我惊慌失措,无法回答这个问题。面试官坚持要知道我的思维过程,所以我提到也许我们可以通过与预期的产品进行比较来获得更多信息,或者也许在从第一遍收集一些信息之后再做第二遍等等,但我真的只是在拍摄在黑暗中,而不是实际上有一个明确的解决方案。

面试官确实试图鼓励我说有第二个方程确实是解决问题的一种方法。在这一点上,我有点不高兴(因为事先不知道答案),并问这是一种通用的(阅读:“有用的”)编程技术,还是只是一个技巧/陷阱的答案。

面试官的回答让我很吃惊:你可以概括该技术来找到 3 个缺失的数字。实际上,您可以将其推广到找到k个缺失的数字。

Qk:如果袋子里正好缺少k个数字,你将如何有效地找到它?

这是几个月前的事了,我仍然无法弄清楚这种技术是什么。显然有一个Ω(N)时间下限,因为我们必须至少扫描一次所有数字,但面试官坚持认为求解技术的时间空间复杂度(减去O(N)时间输入扫描)是在k而不是N中定义的。

所以这里的问题很简单:

  • 您将如何解决Q2
  • 您将如何解决Q3问题?
  • 你将如何解决Qk

澄清

  • 通常有来自 1.. N的N个数字,而不仅仅是 1..100。
  • 我不是在寻找明显的基于集合的解决方案,例如使用位 set,通过指定位的值对每个数字的存在/不存在进行编码,因此O(N)在额外空间中使用位。我们负担不起任何与N成比例的额外空间。
  • 我也不是在寻找明显的排序优先方法。这和基于集合的方法在面试中值得一提(它们很容易实现,并且取决于N,可能非常实用)。我正在寻找圣杯解决方案(它可能实现也可能不实用,但仍然具有所需的渐近特性)。

同样,您当然必须扫描 中的输入O(N),但您只能捕获少量信息(根据k而不是N定义),然后必须以某种方式找到k缺失的数字。


阅读 97

收藏
2022-02-25

共1个答案

小编典典

这是Dimitris Andreou链接的摘要。

记住第 i 次幂的总和,其中 i=1,2,..,k。这减少了求解方程组的问题

a 1 + a 2 + … + a k = b 1

a 1 2 + a 2 2 + … + a k 2 = b 2

a 1 k + a 2 k + … + a k k = b k

使用牛顿恒等式,知道
b i允许计算

c 1 = a 1 + a 2 + … a k

c 2 = a 1 a 2 + a 1 a 3 + … + a k-1 a k

c k = a 1 a 2 … a k

如果您展开多项式 (xa 1 )…(xa k ),系数将恰好是 c 1 , …, c k - 参见Vicatte’s
formulas
。由于每个多项式因子都是唯一的(多项式环是欧几里得域),这意味着
a i是唯一确定的,直到排列。

这结束了一个证明,即记住能力足以恢复数字。对于常数 k,这是一个很好的方法。

然而,当 k 变化时,直接计算 c 1 ,…,c k的方法非常昂贵,因为例如 c k是所有缺失数字的乘积,大小为
n!/(nk)!。为了克服这个问题,在 Z q
field
中执行计算,其中 q
是一个素数,使得 n <= q < 2n - 它由Bertrand
的假设
存在。证明不需要更改,因为公式仍然成立,多项式的因式分解仍然是唯一的。您还需要一种对有限域进行分解的算法,例如BerlekampCantor-
Zassenhaus
的算法。

常数 k 的高级伪代码:

  • 计算给定数字的 i 次方
  • 减法得到未知数的 i 次方之和。调用总和 b i。
  • 使用牛顿恒等式计算 b i的系数;称他们为 c i。基本上, c 1 = b 1;c 2 = (c 1 b 1 - b 2 )/2; 有关确切公式,请参见 Wikipedia
  • 因式分解多项式 x k -c 1 x k-1 + … + c k。
  • 多项式的根是所需的数字 a 1 , …, a k。

对于变化的 k,使用例如 Miller-Rabin 找到素数 n <= q < 2n,并执行所有数字以 q 为模减少的步骤。

编辑:此答案的先前版本指出,可以使用特征 2 (q=2^(log n)) 的有限域代替 Z q,其中 q 是素数。情况并非如此,因为牛顿公式需要除以不超过
k 的数字。

2022-02-25