简体   繁体   中英

Can you tell me what is the time complexity (Big-O) of my function?

Function receives an array, length of array and number of consecutive elements of an array. I run an array and look for the maximum sum of 'K' consecutive elements

#include <iostream>

using std::cin;
using std::cout;
using std::endl;

int GetLargestSum(int array[], int length, int k)
{
    int largestSum = 0;
    int previousSum = 0;
    for (int i = 0; i <= length - k; i++){
        if (i == 0){
            for (int j = 0; j < k; j++){
                largestSum += array[j];
            }
            previousSum = largestSum;
        } else{
            int currentSum = previousSum - array[i - 1] + array[i + k - 1];
            if (currentSum > largestSum){
                largestSum = currentSum;
            }
            previousSum = currentSum;
        }
    }
    return largestSum;
}

int main(){
    int k = 3;
    int array[] = {1, -3, 4, 1, 7, -5, 9};
    cout << "Largest sum of " << k << " consecutive elements of an array = " << GetLargestSum(array, 7, 3);
}

Not a direct answer but a hint:

As noted in my comment, you can prepend the inner for loop to the outer. The result is shown below. I've also removed the redundant variable previousSum and compute the initial sum in currentSum . My function should behave identical to yours, provided that k <= length .

int GetLargestSum(int array[], int length, int k)
{
    int currentSum = 0;
    for (int j = 0; j < k; j++) {
        currentSum += array[j];
    }

    int largestSum = currentSum;
    for (int i = 0; i < length - k; i++) {
        int currentSum += array[i + k] - array[i];
        if (currentSum > largestSum) {
            largestSum = currentSum;
        }
    }
    return largestSum;
}

i still starts at 0 , because I removed the - 1 's in the index accesses and do a strict less comparison in the for-condition ( < instead of <= ). i is now always the index of the summand that's "removed" from currentSum next.

From my understanding, the code does the following:

  • first, traverses the first K elements and get the sum
  • From now, it will just add the next incoming element and remove the first element of the current window and check if this sum is greater or lesser compared to the current sum.

So this way you traverse the array only once. So O(N) (N is length of array)

The point of analysing complexity is to find out largely how much time (time complexity), storage (storage complexity) or memory (memory complexity) an algorithm is using. For this we tend to think about (infinitely) large dimensions, because if the dimensions are very small, we tend not to care them about too much. Your algorithm depends on the number of elements and on the number of consecutive elements.

Assuming that there are (infinitely) many elements, nothing stops k from being large either. In the first step of iterating all elements, but only in the first step (.) you do an O(k)-complex loop, After that you continue to proceed looping your elements and you perform an O(1) operation on each step, n times. which is n * O(1) = O(n).

Now, you have O(k) + O(n), which, since there is no parallelization between the two and no other tricks, results in O(k + n). Since k < n, O(k + n) < O(2n) and O(2n) = O(n), basically you have a linear algorithm.

The if (i == 0)... else... is an obfuscated way of writing the same thing outside of the loop and starting the loop at 1 :

int GetLargestSum(int array[], int length, int k)
{
    int largestSum = 0;
    int previousSum = 0;

    for (int j = 0; j < k; j++){
        largestSum += array[j];
    }
    previousSum = largestSum;

    for (int i = 1; i <= length - k; i++){
        int currentSum = previousSum - array[i - 1] + array[i + k - 1];
        if (currentSum > largestSum){
            largestSum = currentSum;
        }
        previousSum = currentSum;
    }
    return largestSum;
}

Now we can remove all parts that take constant number of operations:

int GetLargestSum(int array[], int length, int k)
{
    // init something 

    for (int j = 0; j < k; j++){
        // do something
    }

    // do something

    for (int i = 1; i <= length - k; i++){
        // do something
    }
    return largestSum;
}

And we can see that the complexity is O ( max( k, length-k) ) and as k <= length this is just O( length )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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