Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 数组作业问题_Arrays_Algorithm - Fatal编程技术网

Arrays 数组作业问题

Arrays 数组作业问题,arrays,algorithm,Arrays,Algorithm,您将获得一个整数介于1和1000000之间的数组。一个整数在数组中存在两次。你如何确定哪一个?你能想出一种使用少量额外内存的方法吗 算法: 解决方案1: 有一个哈希表 遍历数组并将其元素存储在哈希表中 一旦您找到一个已经在哈希表中的元素,它就是dup元素 赞成的意见: 它以O(n)时间运行,仅通过一次 欺骗: 它使用O(n)个额外内存 解决方案2: 使用合并排序对数组进行排序(O(nlogn)时间) 再次解析,如果两次看到一个元素,就得到了dup。 赞成的意见: 它不使用额外的内存

您将获得一个整数介于1和1000000之间的数组。一个整数在数组中存在两次。你如何确定哪一个?你能想出一种使用少量额外内存的方法吗

算法:

  • 解决方案1:
  • 有一个哈希表
  • 遍历数组并将其元素存储在哈希表中
  • 一旦您找到一个已经在哈希表中的元素,它就是dup元素
    • 赞成的意见:
      • 它以O(n)时间运行,仅通过一次 欺骗:
        • 它使用O(n)个额外内存
      • 解决方案2:
      • 使用合并排序对数组进行排序(O(nlogn)时间)
      • 再次解析,如果两次看到一个元素,就得到了dup。
        • 赞成的意见: 它不使用额外的内存 欺骗:
          • 运行时间大于O(n)

          你们能想出更好的解决方案吗?这个问题有点模棱两可;当请求为“which one”时,是指返回重复的值,还是返回重复值序列中的位置?如果是前者,以下三种解决方案中的任何一种都会起作用;如果是后者,那么只有前者会有所帮助

          解决方案#1:假设数组是不可变的 构建位图;在遍历数组时设置第n位。如果位已设置,则您已找到重复的位。它以线性时间运行,适用于任何大小的数组

          位图将使用数组中尽可能多的值创建。在遍历数组时,检查数组中的第n位。如果已设置,则已找到副本。如果不是,则设置它。(这样做的逻辑可以在该类的Wikipedia条目中的伪代码中看到。)

          解决方案2:假设数组是可变的 对数组排序,然后进行线性搜索,直到当前值等于上一个值。使用的内存最少。更改排序算法以在比较操作期间检测重复项并提前终止的额外点数

          解决方案#3:(假设数组长度=1000001)
        • 对数组中的所有整数求和
        • 从中减去整数1到1000000(含1000000)之和
        • 剩下的将是您的复制值
        • 这几乎不需要额外的内存,如果同时计算和,可以一次完成

          缺点是需要进行整个循环才能找到答案


          其优点是简单,而且很有可能它实际上比其他解决方案运行得更快。

          假设从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)通行证

          提示:使用XOR A==0和0 XOR A==A的属性。

          查找所有重复项的问题如何?这可以在不到一个小时内完成吗
          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)