不久前我有一次有趣的工作面试经历。问题开始很简单:
Q1:我们有一个袋子,里面装着数字
1
,2
,3
,…,100
。每个数字只出现一次,所以有100个数字。现在从袋子里随机挑选一个数字。找到丢失的数字。
当然,我以前听过这个面试问题,所以我很快就回答了:
A1:嗯,数字
1 + 2 + 3 + … + N
的和是(N+1)(N/2)
(见wikipedia:算术级数和)。对于N = 100
,和是5050
。因此,如果所有数字都存在于袋子中,那么总和将恰好是
5050
。由于缺少一个数字,总和将小于这个,差的是那个数字。所以我们可以在O(N)
时间和O(1)
空间中找到丢失的数字。
在这一点上,我认为我做得很好,但突然间,问题发生了意想不到的转变:
Q2:这是正确的,但是现在如果两个数字丢失,你会怎么做?
我之前从未见过/听说过/考虑过这种变化,所以我很恐慌,无法回答这个问题。面试官坚持要知道我的思考过程,所以我提到也许可以通过与预期产品的对比来获得更多信息,或者在收集了第一遍的一些信息后再做第二遍等。但我真的只是在黑暗中拍摄,而不是真正有一个明确的解决方案。
面试官确实试图鼓励我说,有第二个方程确实是解决问题的一种方法。在这一点上,我有点不高兴(因为事先不知道答案),并问这是一个通用的(阅读:“有用”)编程技术,或者它只是一个技巧/陷阱的答案。
面试官的回答让我大吃一惊:你可以把技术推广到找到3个缺失的数字。事实上,你可以把它推广到找到k个缺失的数字。
qk:如果包里正好缺少k的数字,你如何有效地找到它?
这是几个月前的事了,我仍然不明白这种技术是什么。显然有一个Ω(N)
的时间下限,因为我们必须至少扫描一次所有数字,但面试官坚持认为求解技术的时间和空间复杂性(减去O(N)
时间输入扫描)在k而不是N中定义。
所以这里的问题很简单:
O(N)
位。我们无法承受与N成比例的任何额外空间。因此,当然,您必须扫描O(N)
中的输入,但您只能捕获少量信息(根据k而不是N定义),然后必须以某种方式找到k缺失的数字。