Arrays 数组作业问题
您将获得一个整数介于1和1000000之间的数组。一个整数在数组中存在两次。你如何确定哪一个?你能想出一种使用少量额外内存的方法吗 算法:Arrays 数组作业问题,arrays,algorithm,Arrays,Algorithm,您将获得一个整数介于1和1000000之间的数组。一个整数在数组中存在两次。你如何确定哪一个?你能想出一种使用少量额外内存的方法吗 算法: 解决方案1: 有一个哈希表 遍历数组并将其元素存储在哈希表中 一旦您找到一个已经在哈希表中的元素,它就是dup元素 赞成的意见: 它以O(n)时间运行,仅通过一次 欺骗: 它使用O(n)个额外内存 解决方案2: 使用合并排序对数组进行排序(O(nlogn)时间) 再次解析,如果两次看到一个元素,就得到了dup。 赞成的意见: 它不使用额外的内存
- 解决方案1:
- 有一个哈希表
- 遍历数组并将其元素存储在哈希表中
- 一旦您找到一个已经在哈希表中的元素,它就是dup元素
- 它以O(n)时间运行,仅通过一次
欺骗:
- 它使用O(n)个额外内存
- 解决方案2:
- 使用合并排序对数组进行排序(O(nlogn)时间)
- 再次解析,如果两次看到一个元素,就得到了dup。
- 运行时间大于O(n)
- 对数组中的所有整数求和
- 从中减去整数1到1000000(含1000000)之和
- 剩下的将是您的复制值 这几乎不需要额外的内存,如果同时计算和,可以一次完成 缺点是需要进行整个循环才能找到答案
-
赞成的意见:
-
赞成的意见:
它不使用额外的内存
欺骗:
你们能想出更好的解决方案吗?这个问题有点模棱两可;当请求为“which one”时,是指返回重复的值,还是返回重复值序列中的位置?如果是前者,以下三种解决方案中的任何一种都会起作用;如果是后者,那么只有前者会有所帮助 解决方案#1:假设数组是不可变的 构建位图;在遍历数组时设置第n位。如果位已设置,则您已找到重复的位。它以线性时间运行,适用于任何大小的数组 位图将使用数组中尽可能多的值创建。在遍历数组时,检查数组中的第n位。如果已设置,则已找到副本。如果不是,则设置它。(这样做的逻辑可以在该类的Wikipedia条目中的伪代码中看到。) 解决方案2:假设数组是可变的 对数组排序,然后进行线性搜索,直到当前值等于上一个值。使用的内存最少。更改排序算法以在比较操作期间检测重复项并提前终止的额外点数 解决方案#3:(假设数组长度=1000001)
其优点是简单,而且很有可能它实际上比其他解决方案运行得更快。假设从1到1000000的所有数字都在数组中,则从1到1000000的所有数字之和为
(1000000)*(1000000+1)/2=500000*1000001=500000500000
所以只要把数组中的所有数字相加,减去500000500000,剩下的数字就是两次出现的数字
O(n)时间和O(1)内存
如果假设不成立,您可以尝试使用-它们可以比哈希表存储得更紧凑(因为它们只存储存在的事实),但它们确实存在误报的风险。但是,通过我们选择在bloom过滤器上花费多少内存,可以限制这种风险
然后,我们可以使用bloom过滤器在O(n)时间内检测潜在的重复项,并在O(n)时间内检查每个候选项。我建议编写一个比较排序函数的实现,该函数在发现dup后立即退出,从而无需额外的内存需求(显然,取决于您选择的算法)和最坏情况下的O(nlogn)时间(同样,取决于算法),而不是最佳(和平均值,取决于…)情况下的O(nlogn)时间 例如,就地合并排序的实现 此python代码是:
作为解决方案(2)的变体,您可以使用。无需额外内存,并且将在中运行 线性时间。你可以说,时间也受数字表示大小的影响,但你已经给出了界限:基数排序在时间O(kn)中运行,其中k是每次通过时可以对ar进行排序的位数。这使得整个排序算法O(7n)加上检查重复数的O(n)——即O(8n)=O(n) 优点:
- 没有额外的内存
- O(n)
- 需要八个O(n)通行证
O(n ln n)时间?(排序和扫描)(如果要恢复原始数组,请携带原始索引并在结束后重新排序,这可以在O(n)时间内完成)通过对整数进行就地排序来对其进行排序。如果出现“冲突”,则会找到正确的数字 空间复杂度O(1)(与可以覆盖的空间相同)
时间复杂度小于O(n)因为在结束之前,你会统计地找到collison。一个做得很好的家庭作业问题的好例子,+1IRC,合并排序是面向列表的,而不是面向数组的。转换肯定会消耗内存。你可能最好使用面向数组的快速排序。据我所知,合并排序仍然可以用于数组.然而,我只是想说,这是一个最好的例子,说明了作业问题应该是怎样的。问题以及已经完成的工作都已经发布了。是否可以说数组的长度正好是1000001,并且1到1000000之间的每个数字都只包含在这个数组中一次,除了一个是c之外完全包含两次?只有当数组包含1到1000000之间的所有整数加上一个double(所以1000001个元素)时才有效,不是吗?很好的一点;我假设数组包含所有整数。太糟糕了;这是一个很好的答案:)这与哈希表相同,您可以
def findDuplicate(arr):
orig_len = len(arr)
if orig_len <= 1:
return None
pivot = arr.pop(0)
greater = [i for i in arr if i > pivot]
lesser = [i for i in arr if i < pivot]
if len(greater) + len(lesser) != orig_len - 1:
return pivot
else:
return findDuplicate(lesser) or findDuplicate(greater)
def findDuplicate(arr):
orig_len = len(arr)
if orig_len <= 1:
return None
pivot = arr.pop(0)
greater = [arr.pop(i) for i in reversed(range(len(arr))) if arr[i] > pivot]
lesser = [arr.pop(i) for i in reversed(range(len(arr))) if arr[i] < pivot]
if len(arr):
return pivot
else:
return findDuplicate(lesser) or findDuplicate(greater)
def findDuplicate(full):
import copy
q = [full]
while len(q):
arr = copy.copy(q.pop(0))
orig_len = len(arr)
if orig_len > 1:
pivot = arr.pop(0)
greater = [arr.pop(i) for i in reversed(range(len(arr))) if arr[i] > pivot]
lesser = [arr.pop(i) for i in reversed(range(len(arr))) if arr[i] < pivot]
if len(arr):
return pivot
else:
q.append(greater)
q.append(lesser)
return None
def findDuplicate(arr):
arr = sorted(arr)
prev = arr.pop(0)
for element in arr:
if element == prev:
return prev
else:
prev = element
return None
def singleton(array):
return reduce(lambda x,y:x^y, array)