【问题标题】:What is the time complexity of adding an element at the beginning of an ArrayList?在 ArrayList 开头添加元素的时间复杂度是多少?
【发布时间】:2013-05-27 17:22:14
【问题描述】:

假设我在这个数组中有一个带有 n 个元素的 ArrayList,我在开头添加了一个元素:

myArrayList.add(0,'some value');

这个操作的时间复杂度是多少?

Java Doc 没有指定这一点。

还有

刚开始学Java,看到一句话

An ArrayList in Java is a List that is backed by an array.

这里的“支持”是什么意思?谢谢!

【问题讨论】:

  • 表示ArrayList是一个实现,List是一个接口。
  • 从技术上讲,ArrayList 在某种意义上只是一个数组。它使用 System.arraycopy 方法来处理添加和删除元素。在这种情况下,它将创建两个数组,一个来自 0-0(空),另一个来自 (0-n)。然后它创建一个长度为+1的新数组并将它们组合在一起,将新元素放入相应的索引处。

标签: java


【解决方案1】:

在数组的开头添加一个元素是 O(n) - 它需要将所有现有元素移动一个位置。

数组列表中的所有元素都存储在一个连续的数组中。如果您添加的元素多于数组的当前大小 - 它将自动增长以适应新元素。

添加到末尾是 O(1) 分摊到多次插入。

【讨论】:

  • 我知道 O(n) 是正常情况,但我实际上是在问 Java 在这种情况下是否有一些魔力(像 Louis Wasserman 提到的那样)?抱歉不够清楚!
  • “这个案子”是什么意思?
  • @LouisWasserman 对不起,我的意思是“这个操作”。这个操作通常需要 O(n) 但我想知道 Java 的实现是否有一些“智能方式”来在 ArrayList 的开头添加元素。您能否详细说明一下为什么需要线性时间?
【解决方案2】:

ArrayList.add(0, element)需要线性时间,但常数很低,因为它可以使用极快的System.arraycopy

【讨论】:

    【解决方案3】:

    ArrayList 文档在这一点上确实晦涩难懂——我刚才在 SE11 中查看了它,自 Collections Framework 的第一个版本(Java 1.2)以来它没有改变。

    我相信 ArrayList 文档作者的意图是指定,在任何 Java 实现中,附加操作(即add(E e) 方法)必须在恒定摊销时间内运行,并且列表插入操作(即add(int index, E e) 方法)必须在O(n) 时间运行,其中n 是列表的大小。

    【讨论】:

      【解决方案4】:
      • 从头开始构建列表并在开头添加大量元素以二次时间运行:O(n2)。
      • 将所有元素添加到列表末尾,然后调用 Collections.reverse(list) 以线性时间运行:O(n)。

      【讨论】:

        猜你喜欢
        • 2019-02-02
        • 2017-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-24
        • 2014-05-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多