【问题标题】:Remove repeat numbers so far removes next number Big O(n)到目前为止删除重复数字会删除下一个数字 Big O(n)
【发布时间】:2019-09-12 23:25:47
【问题描述】:

问题是要删除重复的数字。然后,将数字保留在数组中,不要重复其他数字。例如, [0, 0, 1, 1, 2, 2, 1, 1 , 2, 2] 将是 [0, 1, 2 ] 这些数字应该达到时间复杂度 Big O(n) 和空间复杂度 O (1)。

到目前为止,我所拥有的是下一个数字检查下一个。它没有得到更远的数字。例如: [ 0, 1, 2 ,3 , 4, 5, 6, 2, 8, 9 ] 2 距离较远,但未通过下面的代码进行检查。 D[i+1]

我不能使用哈希映射或哈希集。

    while (i < A.length) {
        i++;
        D = A;
        if (i < A.length - 1) {
            if (A[i] == D[i+1]){
                B[i] = D[i + 1];
            } else
                A[i] = A[i];
        }
    }

【问题讨论】:

  • 你必须使用相同的数组还是可以将结果复制到一个新的数组中?
  • 我不确定你能在 O(n) 中做到这一点,我能想到的一切都像 O(n + 10) 或更糟。想到的第一个解决方案是使用大小为 10 的临时数组。然后遍历有问题的数组并增加值 ++ 的偏移量。然后结果数组中任何不为零的东西都是所需的值,按顺序。问题是您需要遍历导致 n + 10 的结果数组。我假设“空间复杂度 O(1)”意味着它不会随着 n 的复杂度而增长,但是它比 n 大。
  • 您可以使用不同的数组。这个有可能。这是家庭作业。
  • 如果您使用哈希表/集,您可以跟踪重复的数字,您的摊销复杂度将为 O(n)。但是,O(1) 的空间复杂度意味着您不能使用任何额外的内存。例如,对数组进行排序将是 O(n*log n),并且不会产生 [3 1 5] 的“稳定”输出。你确定空间复杂度吗?
  • 我忘了说我不能使用哈希表。有人解释说有两个指针。第一个检查第二个。然后,如果正确,则正确移动。左边留着。如果它是错误的,正确的也会移动。基本上,只有当有新的重复数字时,左边才会移动。

标签: java time-complexity big-o


【解决方案1】:

您必须“检查所有前面”,而不是“检查下一个”。

那么问题就变成了,“如何在恒定时间内检查一个数字是否存在于任意数量的其他元素中”?

使用HashSet。基于散列的结构的所有操作都是 O(1)。

考虑使用HashSetadd()contains()这两种方法。

我把写的代码留给你...

【讨论】:

  • 我不能使用哈希映射或哈希集。
  • @Michele 然后你可以自己写
  • 并且使用额外的哈希集/表会导致 O(n) 的空间复杂度不恒定。
【解决方案2】:

如果输入数组未排序(并且根据您的话 - 它不是),您无法在 O(n) 时间和 O(1) 空间中完成任务。

这是不可能的,因为要删除元素,您必须检查数组中之前的任何位置或之后的任何位置是否存在重复项。

要检查重复项,您必须:

  • 扫描输入数组(这将导致O(n^2)整个算法的时间)
  • 使用额外的空间,例如通过使用Set(这将导致O(n)时间和O(n)空间)。

所以基本上你必须以时间换取空间,反之亦然。

【讨论】:

    【解决方案3】:

    这可能是不可能的,除非数组使用链表排序或将元素标记为 Integer.MIN_VALUE,“空间和时间权衡”应用此原则如果我们需要更快的时间,那么我们需要权衡空间和反之亦然。

    • 如果使用数组,那么您只需将重复元素标记为 Integer.MIN_VALUE(在 java 中或在 c/c++ 中为 -2^16) 你可以忽略这个值。
    • 如果使用链表且数组已排序,则只需检查下一个节点 与前一个节点并删除下一个重复节点。

    【讨论】:

      猜你喜欢
      • 2022-07-16
      • 2015-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多