有一个大小为10,000的数组。它以随机顺序存储数字1到10,000
每个号码只出现一次。
现在,如果从该数组中删除任何数字,并且任何其他数字都复制到数组中。
我们如何确定哪个数字是重复的,复杂度最低?
注意:我们无法使用其他阵列。
答案 0 :(得分:6)
最快的方法是进行O(N)就地分类。
从数组的第一个位置a[0]
开始。假设它具有值5
。您知道5
属于a[4]
,因此交换位置0
和4
。现在,a[0]
中有一个新值。将其交换到需要去的地方。
重复a[0] == 1
,然后转到a[1]
并交换到a[1] == 2
等。
如果您在任何时候最终尝试交换两个相同的值,那么您已找到副本!
运行时:O(N)具有非常低的系数和提前退出。需要存储:零。
奖金优化:计算已发生的掉期次数,并在n_swaps == array_size
时提前退出。当我实施a similar algorithm来排列序列时,这导致了15%的改善。
答案 1 :(得分:5)
计算元素的总和和平方和(对于平方和,您将需要64位值)。从这些中你可以恢复哪个元素被修改:
减去未修改数组的预期值。 如果x被移除并且y重复,则得到差值y - x求和,y 2 - x 2 =(y + x)(y - x)平方和。 从那以后很容易恢复x和y。
编辑请注意,这可能比鸽舍排序更快,因为它在阵列上线性运行,因此对缓存更友好。
答案 2 :(得分:1)
为什么不简单地使用第二个数组或其他数据结构,如哈希表(哈希表,如果你愿意,取决于内存/性能权衡)。第二个数组将简单地存储原始数组中的数字计数。现在只需在原始数组的访问函数中添加+/-即可立即得到您的信息。
ps当你写“我们不能使用另一个数组”时 - 我假设你不能改变ORIGINAL数据结构。但是,可以使用其他数据结构......
答案 3 :(得分:0)
对数组进行排序,然后迭代直到你连续输入两个相同的数字。