1

At every recursive call I choose 1 more of current denomination or no more of current denomination. I sort the denominations in descending order and use a cache of seen remaining amount. Since I try the higher denomination combinations first, the cache should theoretically have the optimal minimal values for the target remaining amount.

func coinChange(coins []int, amount int) int {
    sort.Slice(coins, func(i, j int) bool {
        return coins[i] > coins[j] 
    })
    cache := map[int]int{}
    var coinChangeDp func(i, target int) int
    coinChangeDp = func(i, target int) int {
       if target == 0 {
           return 0
       }
       if i >= len(coins) {
           return -1
       }
       cur := coins[i]
       if cur == target {
           cache[target] = 1
           return 1
       }
       cached, ok := cache[target]
       if ok {
           return cached
       }
       if cur < target {
           amt := coinChangeDp(i, target-cur) 
           if amt != -1 {
               amt = 1 + amt
           }
           otherWay := coinChangeDp(i+1, target)
           if otherWay == -1 && amt == -1 {
               return -1
           } else if amt == -1 {
               cache[target] = otherWay
               return otherWay
           } else if otherWay == -1 {
               cache[target] = amt
               return amt
           } else if amt < otherWay {
               cache[target] = amt
               return amt
           } else {
               cache[target] = otherWay
               return otherWay
           }
       }
       return coinChangeDp(i+1, target)
    }
    return coinChangeDp(0, amount)
}

It fails on this test case coins= [357,239,73,52] amount = 9832

You can try running the code here: https://leetcode.com/problems/coin-change

Thomas
  • 6,032
  • 6
  • 41
  • 79
  • can you turn that into a complete reproducible example with hard coded input and clear expectations for output? – erik258 Aug 25 '23 at 02:20
  • There are multiple issues with this code, it's easier to rewrite from scratch than fix them all. But instead of fixing the code, it'd probably be more constructive to fix understanding issues. Can you write down what you think the algorithm does, either in comments or separately? – Marat Aug 25 '23 at 02:48
  • @Marat First set up cache and sort denominations in descending order The core of the recursive function is 1. first check the minimum amount of coins we can use with the denominations, assuming we can use any amount of coins[i] ... coins [ len(coins) -1 ], next check the minimum with i+1, meaning we check the minimum without ever including coin[i]. The minimum of these is the answer – Thomas Aug 25 '23 at 03:03
  • the total number of ways to make amount = 9832 with coins = [357,239,73,52] is 539. but the question does not say what it is trying to find -- maybe it's the smallest number of coins, instead? – Will Ness Aug 25 '23 at 08:34
  • you can check out a memoizing code [here](https://stackoverflow.com/a/76616326/849891). it finds the total number of ways. you can probably change the accumulation from + to min_by_length there, or something. – Will Ness Aug 25 '23 at 08:49
  • @Thomas So, we are taking a minimum of "use a coin of this denomination and reduce total amount" and "skip a coin of this denomination". Can you explain the cache part? – Marat Aug 25 '23 at 15:16

0 Answers0