计算列表中哪个整数缺失的最佳方法是什么?

时间:2012-01-23 04:03:53

标签: algorithm

我最近在接受采访时问他技术问题。一个是如何计算缺少长度为n-1的列表中的哪个数字。该列表包含从1到n的每个数字,除了i,其中1< = i< = n。这些数字不合适。我的解决方案是将它们全部加起来,然后从1到n的数字的计算中减去它,通过将n加1并且适当地乘以n / 2或(n-1)/ 2。但我觉得有一种更好的方法可以做到这一点。什么是最佳解决方案?

4 个答案:

答案 0 :(得分:5)

在我看来,你的答案已经足够好了。

但有些人 - 也许你的面试官就是其中之一 - 担心溢出等等。在这种情况下,请使用XOR而不是添加。

要获得从0到n的整数的XOR,在循环时只需将数组索引进行异或。给定从0到n的整数的XOR,以及数组元素的XOR,你只需将其中的两个异或一起得到缺少的元素。

P.S。从1到n的整数之和总是(n + 1)* n / 2

答案 1 :(得分:0)

在迭代数组以计算总和时,您可以检查数字是否重复。

答案 2 :(得分:0)

你的方法绝对没问题。它在空间和时间方面都是最佳的。溢出可能是唯一的问题。

另一种可能的方法是使用hashSet。创建具有值1-> N的初始哈希值。现在,对于您在列表中遇到的每个数字 - 从hashSet中删除该值。最后,hashSet中保留的值是缺失值。

该方法的时间和空间复杂度为O(N)。你的方法(禁止溢出)是时间上的O(N)和O(1)复杂度。增加的'n'空间因素是消除溢出的成本。

答案 3 :(得分:0)

你的解决方案非常适合一次更改,因为@Nemo指出从1到n的整数总和始终为(n+1) * n/2

值得指出的是,你的方法是多线程的(并且可能适用于非常大的N值),将数组拆分为部分,然后在线程中获取每个数组部分的总和,然后添加这些部分总和。这取决于线程的开销与在数组中添加数字的比较。

如果您担心溢出,并且您的值始终为int32(因为大多数.Length值包含数组),那么只需将和存储为int64,即所有正整数值的总和{{1}它仍然能够适合带有(((long)int.MaxValue) +1L) * (int.MaxValue / 2) = 2305843007066210304的int64。

其他人提到的另一个答案是对每个项目进行异或并保持正在运行的XOR,但是您需要计算出公式以在.MaxValue = 9223372036854775807时间内获得预期的总XOR。

面试官很可能希望看到你是否意识到O(1)解决方案带有O(N)内存(你的回答是),而不是对数组进行排序,而且对于非常大的O(1)

为了进一步改进代码中的解决方案,可以使用指针来访问数组而不是索引值(如果你的代码是C#将是一个合理的改进)。