簡體   English   中英

遍歷數組列表的時間復雜度

[英]time complexity for iterating through an array list

我有一個我遍歷的數組列表。 在每次迭代中,我調用get()來獲取一個元素,如果該項目通過某個條件,則使用add()其添加到新的數組列表中

List<Item> items = new ArrayList<Item>();
List<Item> lessItems = new ArrayList<Item>();
for(int index = 0; index < items.size(); index++){
    Item toCheck = items.get(i);
    if(toCheck meets some condition){
        lessItems.add(toCheck);
    }
}

我不確定這里的時間復雜度是多少。 我在所有項目上調用 get(),所以是 O(n)。 然后我還可能在所有項目上調用 add(),因此還有另一個 O(n)。 對這個不太確定。

  1. 迭代items列表的第一個循環:復雜度為O(n)
  2. 將每個項目插入到列表lessItems :在普通數組中,正如其他人所說的那樣,它將是O(n) 但是 Java 使用攤銷數組實現ArrayList 這意味着在數組末尾插入時,算法僅花費Amortized O(1) 或者你可以說O(1)

所以你的代碼的復雜性是: O(n) * amortized O(1) 簡而言之就是O(n)

另一個參考:

動態數組

附加說明 1:

如果在數組末尾插入的復雜度是O(N) ,那么總復雜度是O(N^2) ,而不是其他答案所說的 O(2*N) 。 因為插入的總復雜度為: 1 + 2 + 3 + ...+ n = n*(n+1)/2

補充說明 2:

正如官方文件所述:

size、isEmpty、get、set、iterator 和 listIterator 操作在恆定時間內運行。 add 操作在分攤常數 time 內運行,即添加 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);
    }

正如源代碼所說,當程序添加使數組大小大於當前容量的元素時,數組將增長。 增長數組的新大小將是:

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

這是一個使插入amortized O(1)的技巧

你正在做一個迭代,這是 O(n)。

您還將項目添加到 ArrayList,這是 O(1) (攤銷

獲取索引也是 O(1)。

所以你做 O(n) 次,O(1) 的操作,這將是O(n)

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*nO(n)

在這種情況下和所有類似的情況下,任何常數k乘以n將表示為O(n)這意味着運行時間隨輸入 ArrayList 的大小線性變化。

對於遍歷數組列表,時間復雜度將為 O(n)。 n 將是列表的大小。

為了使用 get() 獲取值,它將是 O(1),可以使用索引在數組列表中進行隨機訪問。

對於使用 add() 添加值,該值是最后添加的,因此它將是 O(1)。

此操作的時間復雜度為 O(n)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM