简体   繁体   English

时间复杂度(O(n) 怎么样)

[英]Time complexity (How is this O(n))

I am having trouble understanding how this code is O(N).我无法理解这段代码是 O(N)。 Is the inner while loop O(1).是内部while循环O(1)。 If so, why?如果是这样,为什么? When is a while/for loop considered O(N) and when is it O(1)?何时将 while/for 循环视为 O(N),何时为 O(1)?

int minSubArrayLen(int target, vector& nums)
{

   int left=0;
    int right=0;
    int n=nums.size();
    int sum=0;
    int ans=INT_MAX;
    int flag=0;
    while(right<n)
    {
        sum+=nums[right];
        if(sum>=target)
        {
            while(sum>=target)
            {
                flag=1;

                sum=sum-nums[left];
                left++;
            }
        ans=min(ans,right-left+2);
        }
        right++;
    }
   if(flag==0)
   {
       return 0;
   }
    return ans;
}
};

Both the inner and outer loop are O(n) on their own.内部和外部循环本身都是 O(n)。

But consider the whole function and count the number of accesses to nums :但是考虑整个函数并计算对nums的访问次数:

The outer loop does:外循环做:

    sum+=nums[right];
    right++;

No element of nums is accessed more than once through right .通过right访问nums的任何元素都不会超过一次。 So that is O(n) accesses and loop iterations.这就是 O(n) 访问和循环迭代。

Now the tricky one, the inner loop:现在棘手的一个,内循环:

            sum=sum-nums[left];
            left++;

No element of nums is accessed more than once through left . nums的任何元素都不会通过left被多次访问。 So while the inner loop runs many times in their sum it's O(n).因此,虽然内部循环在它们的总和中运行了很多次,但它是 O(n)。

So overall is O(2n) == O(n) accesses to nums and O(n) runtime for the whole function.所以总体上是O(2n) == O(n)访问整个函数的numsO(n)运行时。

Outer while loop is going from 0 till the n so time complexity is O(n).外部while循环从0到n,所以时间复杂度是O(n)。

O(1): int sum= 0; O(1):整数总和= 0; for(int x=0 ; x<10 ; x++) sum+=x; for(int x=0 ; x<10 ; x++) sum+=x; Every time you run this loop, it will run 10 times, so it will take constant time .每次你运行这个循环,它会运行 10 次,所以它会花费恒定的时间。 So time complexity will be O(1).所以时间复杂度将是 O(1)。

O(n): int sum=0; O(n): int sum=0; For(int x=0; x<n; x++) sum+=x; For(int x=0; x<n; x++) sum+=x; Time complexity of this loop would be O(n) because the number of iterations is varying with the value of n.该循环的时间复杂度为 O(n),因为迭代次数随 n 的值而变化。

O(n) or O(1) is just a notation for time complexity of an algorithm. O(n)O(1)只是算法时间复杂度的一种表示法。

  • O(n) is linear time, that means, that if we have n elements, it will take n operations to perform the task. O(n)是线性时间,这意味着,如果我们有n元素,则执行任务需要n操作。

  • O(1) is constant time, that means, that amount of operations is indifferent to n . O(1)是常数时间,这意味着操作量与n无关。

It is also worth mentioning, that your code does not cover one edge case - when target is equal to zero.还值得一提的是,您的代码不涵盖一种极端情况 - 当target等于零时。

Your code has linear complexity, because it scans all the element of the array, so at least n operations will be performed.您的代码具有线性复杂性,因为它会扫描数组的所有元素,因此至少会执行n操作。

Here is a little refactored code:下面是一些重构的代码:

int minSubArrayLen(int target, const std::vector<int>& nums) {
    int left = 0, right = 0, size = nums.size();
    int total = 0, answer = INT_MAX;
    bool found = false;
    
    while (right < size) {
        total += nums[right];

        if (total >= target) {
            found = true;
            while (total >= target) {
                total -= nums[left];
                ++left;
            }

            answer = std::min(answer, right - left + 2);
        }

        ++right;
    }

    return found ? answer : -1;
}

Consider the scenario考虑场景

The array is filled with the same value x and target (required sum) is also x .数组填充了相同的值x并且target (所需的总和)也是x So at every iteration of the outer while loop the condition sum >= target is satisfied, which invokes the inner while loop at every iterations.因此,在外部 while 循环的每次迭代中,条件sum >= target都满足,这会在每次迭代时调用内部 while 循环。 It is easy to see that in this case, both right and left pointers would move together towards the end of the array.很容易看出,在这种情况left right将一起移动到数组的末尾。 Both the pointers therefore move n positions in all, the outer loop just checks for a condition which calls the inner loop.因此,两个指针总共移动n位置,外循环只检查调用内循环的条件。 Both the pointes are moved independently.两个点都是独立移动的。

You can consider any other case, and in every case you would find the same observation.您可以考虑任何其他情况,并且在每种情况下您都会发现相同的观察结果。 2 independent pointers controlling the loop, and both are having O(n) operations, so the overall complexity is O(n). 2个独立的指针控制循环,并且都有O(n)的操作,所以总体复杂度是O(n)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM