簡體   English   中英

如果我調用一個 function,它在一個 for 循環中包含一個 for 循環,那是 O(n^2) 時間還是 O(n)?

[英]If I call a function that contains a for loop inside a for loop, is that considered O(n^2) time or O(n)?

subArraySum 內的 for 循環調用 sumArray,它也包含一個 for 循環。 這會被認為是 O(n^2) 時間嗎? Go 對我來說很簡單,因為這是我的第一個問題,正如您從我的代碼中看到的那樣,我是初學者。 這是我的代碼:

const subArraySum = (arr,n) => {
    let i = 0;
    let result = [];
    for (let j = n-1;j<arr.length;j++) {
        let li = arr.slice(i,j+1);
        result.push(sumArray(li));
        i++;
    }
    return maxResult(result);
}

function sumArray(li) {
    counter = 0;
    for (let k of li) {
        counter+=k;
    }
    return counter;
}

function maxResult(result) {
    let highest = 0;
    for (let k of result) {
        if (k>highest) {
            highest = k;
        }
    }
    return highest;
}

是的,這使它成為 O(n^2),因為復雜性適用於整個算法,無論它如何拆分為函數。 將一些代碼移出命名函數不會改變整體運行時間或它如何依賴於輸入。

有時,當我們調用語言或操作系統的內置函數時,我們可能會將它們視為復雜度未知的黑盒子,因此我們可能會為了計算我們自己算法的復雜度而忽略它們。 但是您通常不能忽略構成算法一部分的您自己的函數的復雜性,因為如果有更有效的方法,您可以選擇重新設計它們。

雖然for和其他循環結構可能會提供一些關於復雜性的基本指南,但分析必須始終考慮迭代次數,而不是依賴於計算嵌套循環的數量。 可以很容易地證明,任意數量的嵌套循環仍然可以導致線性或恆定的時間復雜度(即while (true) { break; } )。

對於您提到的函數, sumArraymaxResult運行n次迭代,其中n與輸入數組元素的計數相匹配。

然而,對於subArraySum ,復雜性並不那么簡單。 我們可以很容易地看到,該函數同時調用sumArraymaxResult ,但是,尚不清楚這些調用與函數輸入之間的關系。

要為某個長度為m數組arr和參數n調用subArraySum ,我們可以看到for循環從n - 1運行到m ,即m - n + 1次,或者在復雜性方面,循環運行次數為O(m - n + 1) = O(m - n) 對於漸近分析的目的,常數 1 被認為是微不足道的(想象一下 10 9和 10 9 + 1 操作之間的差異 - 可能沒有那么多)。

每個循環然后制作一個長度為n - 1的子數組。 這是基於ij迭代變量 - 我在這里可能錯了,但我懷疑實現是錯誤的。 無論如何,這都是一個O(n)操作。

然后通過sumArray (如前所述的O(n)復雜度)對切片進行求和,並插入到另一個數組的后面(攤銷的O(1) )。

因此,循環的每次運行都具有O(n)復雜度。

由於循環運行O(m - n)次並且具有O(n)復雜度,因此總復雜度為O(n * (m - n)) = O(m * n - n^2)

現在讓我們考慮這個術語m * n - n 2 從函數的語義,我們可以假設,它必須始終保持n < m (對於n = m ,復雜性是常數: m * n - n 2 = n 2 - n 2 = 0 - 您可以通過以下方式確認這一點在精神上通過算法,它只會返回 0 而沒有任何循環)。 如果n始終小於m ,則n 2將始終小於m * n ,因此可以忽略。

我們到達循環的O(mn)

最后, maxResult長為O(m - n)的和數組調用maxResult (請記住,我們通過運行O(m - n)次迭代來創建數組,每次向數組添加一個數字)。 這為maxResult調用提供了O(m - n)復雜度。

對於復雜度O(mn) + O(m - n) ,我們可以再次應用n < m並看到第二項總是產生比第一項小的值,因此可以認為對分析來說無關緊要。

所以我們得出了結果,算法的時間復雜度為O(mn) ,其中m是輸入數組的長度, n是子數組的長度。

這完全取決於您在每個 for 循環中使用哪種方法。

讓我們舉個簡單的例子:-

如果你正在使用一個線性遞增的 for 循環(不斷遞增直到條件起作用)並且在它內部(在主體中)有一個調用 function,它的主體中還有另一個線性 for 循環。

因此,時間復雜度為 O(n^2)。 第二個 for 循環將通過第一個 for 循環的每次迭代對 function 的每次調用迭代 n。 但這完全取決於您對這兩個 for 循環采用哪種增量方法和條件(任何)。

暫無
暫無

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

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