1062
|
polygenelubricants · 技术社区 · 15 年前 |
![]() |
1
610
以下是对 Dimitris Andreou's link . 记住i次方的和,其中i=1,2,…,k。这就把问题简化为求解方程组 一 1 +a + ... + 一 =b级 1 1 2 +a 2 k =b级 ... 一 1 k +a 2 k =b级 k 使用 Newton's identities ,了解b 我 1 1 +a 2 k c 2 1 2 1 三 k-1公司 k ... c k 一 2 ... 一 如果展开多项式(x-a 1 )…(x-a) )系数正好是c k Viète's formulas . 因为每个多项式因子都是唯一的(多项式环是一个 Euclidean domain ),这意味着 是唯一确定的,直到排列。 这就结束了一个证明:记住幂足以恢复数字。对于常数k,这是一个很好的方法。 然而,当k变化时,计算c的直接方法 1 ,…,c k k computations in Z q field ,其中q是素数,使得n<=问题<2n-它存在于 Bertrand's postulate . 证明不需要改变,因为公式仍然成立,多项式的因式分解仍然是唯一的。您还需要一个有限域上的因式分解算法,例如one by Berlekamp Cantor-Zassenhaus .
对于变k,求素数n<=问题<2n使用例如Miller-Rabin,并用所有数的约化模q执行步骤。 编辑:这个答案的前一个版本说,而不是Z q ,其中q是素数,可以使用特征2的有限域(q=2^(logn))。事实并非如此,因为牛顿的公式需要除以k以内的数。 |
![]() |
2
249
Muthukrishnan - Data Stream Algorithms: Puzzle 1: Finding Missing Numbers . 它准确地显示了你正在寻找的概括 . 也许这就是你的面试官读到的,以及他提出这些问题的原因。 另请参见 sdcvvc's 直接相关答案 ,其中还包括伪代码(万岁!不用看那些复杂的数学公式:)(谢谢,做得好!)。 |
![]() |
3
179
方块字 数字的一部分。 然后我们可以把问题简化为
在哪里?
|
![]() |
4
144
正如@j\u random\u hacker指出的,这与 Finding duplicates in O(n) time and O(1) space 我的答案在这里也适用。
假设“bag”由一个基于1的数组表示
首先,我们扩展阵列
第二个循环排列扩展数组,以便if元素
第三个循环打印数组的索引
|
![]() |
5
131
|
![]() |
6
37
不确定,如果这是最有效的解决方案,但我会循环所有条目,并使用位集记住设置了哪些数字,然后测试0位。 我喜欢简单的解决方案,我甚至相信,它可能比计算和,或平方和等更快。 |
![]() |
7
34
|
![]() |
8
17
基于数字和的解决方案的问题是,它们没有考虑到存储和处理具有大指数的数字的成本。。。在实践中,为了使它适用于非常大的n,需要使用一个大的数字库。我们可以分析这些算法的空间利用率。 我们可以分析sdcvvc和dimitrisandreou算法的时间和空间复杂度。 储存:
使用的总存储空间:
总使用时间:
如果这个时间和空间是令人满意的,您可以使用一个简单的递归 算法。让b!我是包里的第i个条目,n前面的数字
使用的存储:
|
![]() |
9
14
等一下。如问题所述,袋子里有100个数字。不管k有多大,这个问题都可以在固定的时间内解决,因为你可以使用一个集合,在一个循环中最多100-k次的迭代中从集合中删除数字。100是常数。剩下的一组数字就是你的答案。
在我看来,面试官是在问你怎么做 打印输出 在O(k)时间内而不是在O(N)时间内的最终集合的内容。显然,设置了位之后,您必须遍历所有N位,以确定是否应该打印数字。但是,如果您更改集合的实现方式,则可以在k次迭代中打印出数字。这是通过将数字放入一个对象来实现的,该对象将同时存储在哈希集和双链表中。从哈希集中删除对象时,也会从列表中删除它。答案将留在现在长度为k的列表中。 |
![]() |
10
8
由于只缺少2个数字,该算法总是丢弃至少一个分区,因此它保留了
不 使用就地分区,因此此示例不满足空间要求,但它确实说明了算法的步骤:
|
![]() |
11
8
这是一个使用k位额外存储的解决方案,没有任何巧妙的技巧,只是简单明了。执行时间O(n),额外空间O(k)。只是为了证明这个问题可以解决,而不必先阅读解决方案,也不必成为天才:
|
![]() |
12
8
Q2的一个非常简单的解决方案,我很惊讶没有人回答。使用Q1中的方法求两个缺失数字的和。让我们用s来表示它,那么一个缺失的数字小于s/2,另一个大于s/2(duh)。将从1到S/2的所有数字相加,并将其与公式的结果(类似于Q1中的方法)进行比较,找出缺失数字之间的较低值。从S中减去它就可以找到较大的缺失数。 |
![]() |
13
6
对于Q2,这是一个比其他解决方案效率稍低的解决方案,但仍然有O(N)个运行时,占用O(k)个空间。
其思想是运行原始算法两次。在第一个例子中,你得到一个缺失的总数,它给出了缺失数的上界。我们打这个号码吧
因此,您将再次循环所有数字,丢弃第一个间隔中未包含的所有数字。那些是的,你记录他们的总数。最后,您将知道丢失的两个数字中的一个,并扩展到第二个。 我有一种感觉,这种方法可以推广,也许在输入的一次传递过程中,多个搜索可以“并行”运行,但我还没有弄清楚怎么做。 |
![]() |
14
5
这个算法实际上可以扩展为两个缺失的数字。第一步不变。当我们用两个缺失的数字调用GetValue时,结果将是
现在要从val中筛选出a1和a2,我们取val中的任意一个位
|
![]() |
15
4
你能检查一下每个号码是否都存在吗?如果是,您可以尝试以下方法:
如果丢失的数字是
所以你检查一下
|
![]() |
16
3
如果你有两个列表的总和和两个列表的乘积,你可以解Q2。 (l1为原始列表,l2为修改列表)
现在我们知道了(如果a和b是删除的数字):
所以我们可以重新安排:
乘以:
重新排列,使右边为零:
然后我们可以用二次公式求解:
Python 3代码示例:
我不知道sqrt,reduce和sum函数的复杂度,所以我无法计算出这个解决方案的复杂度(如果有人知道,请在下面评论) |
![]() |
17
3
有一种通用的方法来概括这样的流算法。
我们的想法是使用一些随机化的方法,希望能“传播”这些信息
特定对被发送到同一个bucket的概率小于
事实上,通过使用注释中描述的技巧,我们甚至可以比幂和方法更有效。 |
![]() |
18
3
动机如果要解决一般情况的问题,并且可以存储和编辑数组,那么 Caf's solution 是目前为止效率最高的。如果无法存储阵列(流式版本),则 sdcvvc's answer 是目前唯一建议的解决方案类型。
我建议的解决方案是最有效的答案(到目前为止在这个线程上),如果你可以存储问题,但不能编辑它,我的想法是从
Svalorzen's solution
,解决1或2个缺少项的问题。这个解决方案需要
概念
... 然后取缺失数字的平均值:
... 它提供了一个边界:在缺失的数字中,肯定有
数字小于或等于
代码C风格的解决方案(不要以全局变量来评判我,我只是想让代码对非C语言的人可读):
暂时忽略递归,每个函数调用都会
函数调用的数量并不明显
米 --米 2 三 --米 4 --(…)--米 k-1公司 --米
影响
这意味着无论分裂是如何发生的,它总是需要
所以时间复杂度是
讨论
|
![]() |
19
2
我认为这不需要任何复杂的数学方程和理论就可以做到。下面是一个就地O(2n)时间复杂度解决方案的建议: 输入表单假设: #袋数=n #缺失数=k 包中的数字由长度为n的数组表示
数组中缺少的条目(从包中取出的数字)将替换为数组中第一个元素的值。 如果取4,则4的值将变为2(数组的第一个元素)。 此解决方案的关键是,在遍历数组时,通过对该索引处的值求反来标记已访问号码的索引。
|
![]() |
20
2
这是一个解决方案,它不像sdcvvc/Dimitris Andreou的答案那样依赖于复杂的数学,不像caf和collone Panic那样改变输入数组,不像Chris Lercher、JeremyP和其他许多人那样使用巨大的位集。基本上,我从Svalorzen/Gilad-Deutch的Q2思想开始,将其推广到常见情况Qk,并用Java实现,以证明算法是有效的。 这个主意假设我们有一个任意的间隔 我 我们只知道它至少包含一个缺失的数字。通过输入数组一次后,只查看 ,我们可以得到 S码 数量呢 问 我 . 我们通过简单的递减来实现 我是 每次我们遇到一个来自 我 (用于获取 问 )通过减少所有数字的预计算和 我 每次遇到的数字(为了获得 ). 和 问 Q=1 ,意思是 我 只包含一个缺失的数字,而这个数字显然 . 我们标记 完成时(在程序中称为“无歧义”),不作进一步考虑。另一方面,如果 ,我们可以计算平均值 A=S/Q 包含在 我 A 至少有一个严格大于 . 现在我们分手了 在里面 A 分成两个较小的间隔,每个间隔至少包含一个缺失的数字。请注意,我们指定的间隔并不重要 A 如果是整数。 S码 和 问 对于每个间隔分别(但在同一过程中),然后用 Q>1 . 我们继续这个过程,直到没有新的“模糊”区间,也就是说,我们没有什么可分割的,因为每个区间正好包含一个缺失的数字(我们总是知道这个数字,因为我们知道 ). 我们从包含所有可能数字(如 在问题中)。 时空复杂性分析p 我们需要做的是,直到过程停止,永远不超过失踪人数计数 可以得到严格的证明。另一方面,也有一个经验上限 p<日志 2 对于较大的 k . 我们需要对输入数组的每个数字进行二进制搜索,以确定它所属的间隔。这增加了 时间复杂性的乘数。 总的来说,时间复杂度是 O(无)á 最小值(k,对数N)á 对数(k) . 请注意,对于大型 k O(无)á (千) 对于它的工作,算法需要 最多可储存的额外空间 时间间隔,这比 在“位集”解决方案中。
下面是一个实现上述算法的Java类。它总是返回一个
已排序
因为它在第一次通过时就计算出来了。整个数字范围由
为了公平起见,这个类以
测验下面给出了演示这些类用法的简单示例。
|
![]() |
21
1
你可能需要澄清O(k)的含义。
对于任意k,这里有一个简单的解决方案:对于一组数字中的每一个v,累加2^v的和。最后,循环i从1到N。如果与2^i按位AND的和为零,则缺少i(或者在数字上,如果总和除以2^i的下限是偶数。或者
很简单,对吧?O(N)时间,O(1)存储,支持任意k。
所以你可以很聪明的计算和,平方和,立方和。。。求出v^k的和,然后做一些复杂的数学运算来提取结果。但这些数字也很大,这就引出了一个问题:我们谈论的是什么抽象的运作模式?在O(1)空间中有多少是合适的,以及需要多长时间来计算出所需大小的数字? |
![]() |
22
0
很好的问题。我会用一组差来表示Qk。很多编程语言甚至都支持它,比如在Ruby中:
|
![]() |
23
0
你可以试着用 Bloom Filter |
![]() |
24
0
这当然不是批处理预生成的数字包的最快方法,因为整个过程都在运行
|
![]() |
25
0
你可以从对称性(数学语言中的组)的角度来考虑解决方案。不管这组数字的顺序如何,答案应该是一样的。如果你要用
你可以在构建初等对称函数的时候注意
如何判断数组中缺少哪些项?想想多项式
所以我们可以建立多项式,并尝试将其因子化,以找出哪些数字不在集合中,正如其他人所提到的。
最后,如果我们关心大量内存溢出(n次对称多项式的阶数
|
![]() |
26
0
另一种方法是使用残差图过滤。 假设我们有1到4个数字,3不见了。二进制表示如下:, 1=001b,2=010b,3=011b,4=100b 我可以创建如下流图。
请注意,流图包含x个节点,而x是位数。最大边数为(2*x)-2。 所以对于32位整数,需要O(32)空间或O(1)空间。 如果从1,2,4开始去掉每个数的容量,剩下的就是残差图。
最后我将运行如下循环,
现在结果出来了
我将把所给的单子再看一遍,以标明结果是否遗漏。
最后,通过获取节点可以减少误报的数量(以及所需的空间)
|
![]() |
27
0
为了使解释更简单,假设我得到了从1到15的数字,其中有两个丢失了,即9和14,但我不知道。让包看起来像这样: 我们知道每个数字在内部是以位的形式表示的。 对于16之前的数字,我们只需要4位。对于10^9之前的数字,我们需要32位。但是让我们关注4位,然后我们可以推广它。
但现在我们少了两个数字。因此,我们的表示将如下所示(显示顺序是为了理解,但可以是任何顺序):
从左到右扫描袋子,填充上面的数组,使每个位数组的bin包含数字的计数。结果如下:
因此,我们知道有两个数字丢失:一个最2个有效位是10,另一个最2个有效位是11。现在再次扫描列表,并填写一个大小为2的位数组,以获得下面的2个有效数字。这一次,只考虑最2位有效数字为10的元素。我们将使用位数组:
因此,我们可以在一个恒定的空间中找到丢失的数字。我们可以把它推广到100,1000,10^9或任何一组数字。 参考文献:中的问题1.6 http://users.ece.utexas.edu/~adnan/afi-samples-new.pdf |
![]() |
28
-1
我相信我有一个
你有一个
|
![]() |
29
-1
试着找出1到50之间的乘积:
当你把数字一个接一个地取出来时,把它们相乘,得到乘积P2。但此处缺少两个数字,因此P2<第1页。 两个错误项的乘积,a x b=P1-P2。 你已经知道总和了,a+b=S1。
|
![]() |
30
-1
这听起来可能很愚蠢,但是,在第一个问题中,你必须看到包中所有剩余的数字,才能用这个等式把它们加起来找到丢失的数字。 所以,既然你能看到所有的数字,就去寻找丢失的数字。当两个数字丢失时也是如此。我觉得很简单。当你看到袋子里剩下的数字时,用公式是没有意义的。 |
![]() |
feasega · 聚合物模拟-2个节点之间的最短路线,适用于所有节点 9 月前 |
![]() |
Alisa Petrova · 在有向图中更改一对顶点以创建循环 9 月前 |
![]() |
b39b332d · 使用C++标准库实现高效间隔存储 1 年前 |
![]() |
ABGR · 二叉树的直径——当最长路径不通过根时的失败案例 1 年前 |
![]() |
EpicAshman · 数独棋盘程序中同一列和同一行出现两次的数字 1 年前 |