簡體   English   中英

時間復雜度為O(n)而不是O(n ^ 2)如何?

[英]How is the time complexity O(n) and not O(n^2)?

我正在LeetCode.com上解決一個問題:

給定一個由正整數組成的向量nums ,計算並打印子數組中所有元素的乘積小於k的(連續)子數組的數量。

代碼(我在大量在線幫助下編寫的)如下:

class Solution {
public:
    int numSubarrayProductLessThanK(vector<int>& nums, int k) {
        if(nums.empty() || k<=1) return 0;

        int counter=0, left=0, currProd=1;
        for(int i=0; i<nums.size(); i++) {
            currProd*=nums[i];
            while(left<nums.size() && currProd>=k)
                currProd/=nums[left++];
            counter+=i-left+1;
        }

        return counter;
    }
};

雖然我了解發生了什么,但我不明白時間復雜度如何稱為O(n)而不是O(n^2) 恕我直言, ileft都會增加,導致在最壞的情況下兩次訪問nums每個元素-一次通過歸納變量i然后再一次通過left

那么,時間復雜度O(n)如何?

盡管代碼看起來像是O(N^2) -,但要注意的關鍵是:

在for循環中, left永遠不會重置為0,並且在while循環中始終會遞增。

這意味着while循環在整個代碼執行期間最多只能執行N次。 因此,代碼僅在數組中運行兩次,即O(N)

每次執行內循環體時, left遞增1 left是最初為0和從未增長超過nums.size() 因此,內部循環的主體最多執行nums.size()次。

外循環的主體將被精確執行nums.size()次。

因此,函數的執行時間最多為T0 + nums.size() * T1 + nums.size() * T2 ,其中T0是在外循環之外執行代碼所需的時間,T1是執行外部循環所需的時間。執行一次不包括內循環的外循環迭代,T2是執行內循環的一次迭代所需的時間。 此上限的形式為A + nums.size() * B ,其中A和B是一些常量。 因此,函數的執行時間為O(nums.size())

當您有兩個嵌套循環時,整個程序的復雜度最多為 M*N ,其中M是外循環的迭代次數, N是內循環的最大迭代次數。 因此,程序的復雜度滿足O(M*N) 有時可能會找到下界,因為內部循環的迭代次數會有所不同。 在這里,有一個不變量保證內部循環最多執行一定次數的次數,這比O(nums.size() * nums.size())綁定更好。

暫無
暫無

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

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