迭代数组列表的时间复杂度

时间:2016-09-17 00:57:07

标签: java arrays algorithm arraylist data-structures

我有一个我遍历的数组列表。在每次迭代中,我调用 <?php //index.php namespace project\admin; include_once("scInit.php"); use project\model\TimeStamp; $con= new TimeStamp(); /* class TimeStamp is not loaded so now it will run spl_autoloader before generating fatal error passing project\model\TimeStamp as parameter. spl_autoloader will look for scTimeStamp.php in all directories defined in autoload function. */ 来获取一个元素,如果该项经过某个条件,则使用https://api.softlayer.com/rest/v3/SoftLayer_Account/getInvoices.json?resultLimit=0,200&objectMask=mask[createDate,closedDate,typeCode,statusCode,invoiceTotalAmount,invoiceTopLevelItems[id,description,hostName,domainName,totalRecurringAmount,totalOneTimeAmount,parentId,categoryCode,billingItemId,billingItem[id,cancellationDate,createDate,hourlyFlag,lastBillDate,cancellationReason,orderItemId,orderItem[id,order[id,userRecord[username]]]]]]&objectFilter={"invoices":{"invoiceTotalAmount":{"operation":"!=0"},"createDate":{"operation":"betweenDate","options":[{"name":"startDate","value":["7/29/2016 0:0:0"]},{"name":"endDate","value":["7/30/2016 23:59:59"]}]}}}

将其添加到新的数组列表中
get()

我不确定这里的时间复杂程度如何。我在所有项目上调用get(),这样就是O(n)。然后我也在潜在的所有项目上调用add(),因此还有另一个O(n)。这个不太确定。

4 个答案:

答案 0 :(得分:7)

此处所有其他答案错误

  1. 迭代items列表的第一个循环:复杂度为O(n)
  2. 将每个项目插入到列表lessItems的末尾:在正常数组中,正如其他人所说的那样,它将是O(n)。但Java使用amortized arrayArrayList实现。这意味着当在数组末尾插入时,算法仅花费Amortized O(1)。或者你可以说O(1)
  3. 因此代码的复杂性为:O(n) * amortized O(1)。简而言之就是O(n)

    另一个参考:

    dynamic array

    附加说明1:

    如果在数组末尾插入的复杂度为O(N),那么总复杂度为O(N^2),而不是其他答案所说的O(2 * N)。因为插入的总复杂度为:1 + 2 + 3 + ...+ n = n*(n+1)/2

    Addtional Note 2:

    official document所述:

      

    运行size,isEmpty,get,set,iterator和listIterator操作   在恒定的时间。 添加操作以分摊的常量时间运行,   也就是说,添加n个元素需要O(n)时间。所有其他的   操作以线性时间运行(粗略地说)。不变因素   与LinkedList实现相比较低。

    附加说明3:

    以下是我从官方java源代码中获取的grow方法的逻辑:

    private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
    private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;
            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    

    正如源代码所说,当程序添加使数组大小大于当前容量的元素时,Array将会增长。增长阵列的新大小将是:

    int newCapacity = oldCapacity + (oldCapacity >> 1);
    

    这是一个让插入amortized O(1)

    的技巧

答案 1 :(得分:2)

您正在进行迭代,以及O(n)。

您还要将项目添加到ArrayList,其中包含O(1)(Amortized

获取索引也是O(1)。

所以你做O(n)次,操作O(1),这将是 O(n)

答案 2 :(得分:0)

Big-O和类似的符号是时间复杂度的渐近界限。它们丢弃数值系数,用于估算作为输入大小函数的运行时间。

所以,2*n3*n等。表示为O(n)2*nlog(n)3*nlog(n)等。表示为O(nlog(n))

由于add()操作在这种情况下只插入一个元素,因此其运行时间约为(some small constant)k*1,总运行时间为(some constant)j*(n+some constant(k)),换句话说j*n或{ {1}}。

在这种情况下以及所有类似的情况下,任何常数 k 乘以 n 都将表示为O(n),这意味着运行时间随着大小而线性变化。输入ArrayList。

答案 3 :(得分:0)

要遍历数组列表,时间复杂度将为O(n)。 n将是列表的大小。

要使用get()获取值,它将为O(1),可以使用索引在数组列表中进行随机访问。

对于使用add()来添加值,该值将在最后被添加,因此将为O(1)。

此操作的时间复杂度为O(n)。