简体   繁体   中英

Time complexity for a specific recursive algorithm

How should one go about to find the time complexity of sum1 ?

func sum1(x []int) int {
    // Returns the sum of all the elements in the list x.
    return sum(x, 0, len(x)-1)
}

func sum(x []int, i int, j int) int {
    // Returns the sum of the elemets from x[i] to x[j]
    if i > j {
        return 0
    }
    if i == j {
        return x[i]
    }
    mid := (i + j) / 2
    return sum(x, i, mid) + sum(x, mid+1, j)

}

Is it correct that the amount of steps requried for this specific algorithm is T(n)= 1 + 2*T(n/2) ? where n is the amount of elements in the array?

The i>j case can never happen via sum1 unless the user passes in an empty list, so let's ignore it for the calculation of the time complexity.

Otherwise a call to sum(x[], i, j) either returns an element of x , or adds to things together. If the result is the sum of x[i]+x[i+1]+...+x[j] , then it must be the case that there's j-i+1 cases that return an element of x , and ji cases that perform an addition. Thus there must be a total of 2j-2i+1 calls to sum , and so the complexity of sum1 is O(len(x)).

Note that this code is pointless -- it's just a very complicated and overhead-heavy way of doing the same(*) as the naive code for i = 0..n-1 {sum += x[i]} return sum . (*) assuming addition is associative.

If you want a recursive formulation of T(n) (where n is j-i+1), then it's T(1)=1, T(n) = T(floor(n/2)) + T(ceil(n/2)) + 1. You will get the right complexity if you approximate it with T(n)=2T(n/2)+1, but it isn't quite right unless you state that n is a power of 2. This is a common approximation for dealing with divide-and-conquer array algorithms.

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