4

I'm trying to figure out the time complexity of a greedy coin changing algorithm. (I understand Dynamic Programming approach is better for this problem but I did that already). I'm not sure how to go about doing the while loop, but I do get the for loop.

I have the following where D[1...m] is how many denominations there are (which always includes a 1), and where n is how much you need to make change for.

This is my algorithm:

CoinChangeGreedy(D[1...m], n)
    numCoins = 0
    for i = m to 1
        while n ≥ D[i]
            n -= D[i]
            numCoins += 1
    return numCoins
dWinder
  • 11,597
  • 3
  • 24
  • 39
RiseWithMoon
  • 104
  • 2
  • 8

2 Answers2

4

Let look at the edge cases.

At the worse case D include only 1 element (when m=1) then you will loop n times in the while loop -> the complexity is O(n).

If m>>n (m is a lot bigger then n, so D has a lot of element whom bigger then n) then you will loop on all m element till you get samller one then n (most work will be on the for-loop part) -> then it O(m).

Button line: O(max(m,n))

Hope that helps!

dWinder
  • 11,597
  • 3
  • 24
  • 39
  • I guess I don't understand how you loop `n` times when n is decremented by a value that is dependent in the denominations `D[1...m]` array. – RiseWithMoon Nov 14 '18 at 04:45
  • 1
    For the complexity I looked at the worse case - if `m=1` then it will loop `n` times (try to run example). Of course if `m` bigger then the complexity decrease. – dWinder Nov 14 '18 at 04:55
  • Okay that makes sense. What would the best-case be then? – RiseWithMoon Nov 14 '18 at 05:16
  • @dgfrey102790 O(1) when `m=n`. I guess average case will be little bit more then `n/m` when `m – dWinder Nov 14 '18 at 05:58
  • Would it be wrong to say `O(m + n)` instead of `O(max(m, n))`? – qz- Feb 03 '22 at 00:38
  • If we limit denominations to integers then the smallest possible denomination is `m`, and I think we can get a tighter bound from that and say `O(m + n / m)` – qz- Feb 03 '22 at 00:42
1

Thanks for the help. I changed around the algorithm I had to something I could easily calculate the time complexity for. Here's what I changed it to:

CoinChangeGreedy(D[1...m], n)
    numCoins = 0
    for i = m to 1
        if n/D[i] ≥ 1
            numCoins = numCoins + (n/D[i])
            n = n - [(n/D[i]) * D[i]]
    return numCoins

Where I calculated this to have worst-case = best-case \in \Theta(m)

RiseWithMoon
  • 104
  • 2
  • 8