【问题标题】:Big-O run time for adding N items into ArrayList将 N 个项目添加到 ArrayList 的 Big-O 运行时间
【发布时间】:2015-07-20 12:47:32
【问题描述】:

假设我在 Java 中将 N 个项目添加到 ArrayList。最坏情况下的运行时间是多少?我知道添加单个项目可能是 O(N),因为数组可能需要调整大小。当我添加 N 个项目甚至 N 倍时,它不会调整 N 倍的大小,因为(AFAIK)ArrayList 每次调整大小时都会增加一些容量。这意味着某种 log(N) 数量的调整大小。因此,插入 N 个项目似乎应该是 O(N log(N)),但我对此并不完全确定。我正在查看的旧计算机科学考试的答案为 O(N^2)。我错过了什么吗?

int newCapacity = (oldCapacity * 3)/2 + 1; (from this answer)

【问题讨论】:

  • O(N^2) 是如果每次调整大小使阵列容量增加相同数量的成本界限。也许这就是考试问题所要问的。
  • 其实我发现试题的意思是插入到任何位置。这包括前面,它需要把所有东西都往下移。那是 O(N^2)。

标签: java arraylist big-o


【解决方案1】:

dynamic array 在计算机科学的摊销时间分析方面得到了充分的研究。简短的回答是,当从一个空的动态数组开始并添加 N 个元素时,总时间为 O(N)。

您是正确的,当必须执行调整大小时,添加单个项目的最坏情况时间为 O(N),并且 O(log N) 调整大小发生。

但是当我们把这些resize操作加起来,总共只有O(N)个,非常好。下面是一个例子来说明当缩放因子为 2(而不是 ArrayList 的缩放因子为 3/2)时:

N = 64:调整大小为 1、2、4、8、16、32、64。总操作数 = 127(大约 2N)。

【讨论】:

  • 不应该 O(N) 操作执行 log(N) 次导致 O(N log(N)),就像添加到 TreeMap 一样?我知道将 N 项添加到平衡树(不是真正细长的东西)被认为是 O(N log N)。
  • 技术上是的,但 N log N 是一个悲观分析。 O(N) 是紧密分析。
  • 这样想,在 32 次插入之后,您重新分配存储空间并复制 32 个元素;在 64 次插入后,您可以为 64 个元素执行此操作。当您将容器的大小增加一倍时,您花费两倍的时间进行重新分配,但您也只需执行一半的频率。
  • 是的,我可以通过归纳证明任何 N 大约有 2N 次操作。我假设它通常是 f*N,其中 f 是数组调整大小因子。
  • 关闭,但实际上是 f / (f - 1) * N 由于几何级数。 =) 更大的因素有更少的时间开销,但浪费更多的空间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-17
  • 2018-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多