【问题标题】:How to identify the duplicated number, in an array, with minimum compexity?如何以最小的复杂性识别数组中的重复数字?
【发布时间】:2011-08-11 08:45:11
【问题描述】:

有一个大小为 10,000 的数组。它以随机顺序存储数字 1 到 10,000。
每个数字只出现一次。

现在,如果从该数组中删除任何数字,并且将任何其他数字复制到数组中。

我们如何以最小的复杂性识别哪个数字是重复的?

注意:我们不能使用另一个数组。

【问题讨论】:

标签: c math logic


【解决方案1】:

最快的方法是 O(N) 就地鸽巢排序。

从数组的第一个位置a[0] 开始。假设它的值为5。你知道5 属于a[4],所以交换位置04。现在,a[0] 中有一个新值。把它换到它需要去的地方。

重复直到a[0] == 1,然后转到a[1]并交换直到a[1] == 2,等等。

如果您最终尝试交换两个相同的值,那么您已经找到了重复值!

运行时间:O(N),系数非常低,提前退出。所需存储空间:零。

奖励优化:计算发生了多少交换,如果n_swaps == array_size 则提前退出。当我实现 a similar algorithm 来排列序列时,这导致了 15% 的改进。

【讨论】:

    【解决方案2】:

    计算元素的总和和平方和(平方和需要 64 位值)。从这些您可以恢复修改了哪个元素:

    减去未修改数组的预期值。 如果 x 被删除并且 y 重复,则总和的差为 y - x,总和的差为 y2 - x2 = (y + x) (y - x)平方和。 从中很容易恢复 x 和 y。

    编辑:请注意,这可能比鸽巢排序更快,因为它在数组上线性运行,因此对缓存更友好。

    【讨论】:

      【解决方案3】:

      为什么不简单地使用第二个数组或其他数据结构,如哈希表(如果您愿意,可以使用哈希表,取决于内存/性能权衡)。第二个数组将简单地将数字的计数存储在原始数组中。现在只需在原始数组的访问函数中添加一个 +/- 即可立即获得信息。

      ps 当你写“我们不能使用另一个数组”时——我假设你不能改变 ORIGINAL 数据结构。然而,使用额外的数据结构是可能的......

      【讨论】:

        【解决方案4】:

        对数组进行排序,然后遍历,直到连续命中两个相同的数字。

        【讨论】:

          猜你喜欢
          • 2018-05-04
          • 2015-09-28
          • 1970-01-01
          • 1970-01-01
          • 2021-06-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多