Time Complexity of this program solving the coin change problem

Question:

I have created a program shown below, and I am confused as to how to figure out its time complexity. Is it O(ntarget/min(coins)) because a for loop is created each time the function is called, and the function is called target/min(coins) times?

The program solves the coin change problem (although not in a very efficient way!):

You are given an array of coins with varying denominations and an integer sum representing the total amount of money; you must return the fewest coins required to make up that sum.

For this problem

Code:

def count(coins: list[int], target):
    def helper(coins, target, vals = [], answers = set()):
        if target<0:
            vals.pop()
        elif target==0:
            vals.sort()
            answers.add(tuple(vals))
            vals.clear()
        else:
            for coin in coins:
                helper(coins, target-coin, vals+[coin])
            return len(answers)
        
    coins.sort()
    if (answer:=helper(coins, target)): 
        return answer
    else:
        return -1

print(count([2, 5, 3, 6], 10)) # 5
print(count([1, 3, 5, 7], 8)) # 6

Attempt at code explanation (explained for print statement 2):

It starts with finding the most amount of coins that is needed to reach the target or go higher( (1, 1, 1, 1, 1, 1, 1, 1) in this case).

From there it iterates over all the possible values for the last row ((1, 1, 1, 1, 1, 1, 1, 3), (1, 1, 1, 1, 1, 1, 1, 5), (1, 1, 1, 1, 1, 1, 1, 7)). If the sum of the numbers is negative, it removes that value and tries again with a different value.

It adds any solutions (where sum(vals)==target)to the set answers (after sorting it) to prevent duplicates from being counted.

Then it moves to the higher row ((1, 1, 1, 1, 1, 1, 1), (1, 1, 1, 1, 1, 1, 3), (1, 1, 1, 1, 1, 1, 5), (1, 1, 1, 1, 1, 1, 7)). And repeats.

Can anyone explain what is the time complexity of the program along with why? Thanks!

Asked By: Jason Grace

||

Answers:

I have realized that my initial thought was correct: the time complexity is indeed O(nceil(target/min(coins))).

If you take the smallest value in coins, then it will have to call itself ceil(target/min(coins)) times, and with each call start a new for loop, which is an O(n) operation. Therefore, it becomes O(nceil(target/min(coins))) time complexity

Answered By: Jason Grace