【问题标题】:Wouldn't remove for a non dynamic unsorted array list be O(n)?非动态未排序数组列表不会删除 O(n) 吗?
【发布时间】:2015-04-07 06:26:15
【问题描述】:

这属于 stackoverflow.com/help/on-topic 中的“软件算法”,在这种情况下,是从未排序的数组列表中删除项目的软件算法

这是我们在课堂上讨论不同数据结构的大运行时

我的问题是关于删除未排序的非动态数组的值。根据我们的实现方式,这不应该是 O(n)(见下文)

 public void remove(E value) {
    int index = getIndex(value);
    elementData[index] = elementData[size - 1];
    elementData[size - 1] = null;
    size--;
}
public int getIndex(E value) {
   for (int i = 0; i < size; i++) {
       if (elementData[i].equals(value)) {
           return i;
       }
   }
   return -1;
}

虽然我同意这个代码段

elementData[index] = elementData[size - 1];
    elementData[size - 1] = null;
    size--;

将在 O(1) 中运行。我从另一个问题Why is clear an O(n) operation for linked list? 中学到的是,Big Oh“考虑了运行代码必须做的所有事情”,在这种情况下,它包括受 O(n) 约束的 getIndex 函数。 因为 remove 方法由 O(n) 和 O(1) 组成,所以它将在 O(n) 时间内运行。 大家都同意我的评估还是我遗漏了什么?

【问题讨论】:

  • 您的复杂性分析是正确的。我最好的猜测是,您引用的表是指删除由索引而不是值给出的元素,因此对 getIndex 的调用将是多余的。
  • 没有表有删除值并按索引删除

标签: java arrays algorithm arraylist time-complexity


【解决方案1】:

是的,你是对的。您的 getIndex 函数平均在 O(n) 中运行(O(1/2 * n),但我们通常对常量不感兴趣)。 remove 函数中的其他代码以恒定时间运行,因此总运行时间为 O(n + c),其中 c 是一个常数,这意味着总运行时间为 O(n)。

【讨论】:

  • 平均因为该元素通常位于列表的中间?
  • 是的,因为平均而言,元素会在中心找到(给定一个随机数组)。
  • 是的,我一直对一半感到困惑,因为我觉得那是在说元素必须在中心,而它可能在前面或后面。
  • 在一个随机数组中,一个元素在前半部分发生的变化是50%,在后半部分发生的变化是50%。这与取 1,000,000 个介于 0 和 1 之间的随机数相同。将它们全部加起来总是会得到大约 500,000,因为 0 和 1 之间的随机数的平均值是 0.5。
  • 平均需要 n/2 次迭代才能找到正确的索引。没有大O。你说 O(n*1/2) 没有意义是正确的,因为 O(n*1/2) 等于 O(n)。这两个 Big-O 函数完全相同。
猜你喜欢
  • 2015-04-07
  • 2014-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多