Home > Net >  Coin change leetcode in python
Coin change leetcode in python

Time:10-11

I tried to solve on my own the LeetCode problem enter image description here

This is my solution:

from typing import List
class Solution:
    def coinChange(self, nums: List[int], target: int) -> int:      
        def dfs(remainder):
            if remainder<0:
                return None
            if remainder==0:
                return []         
            shortest_combination=None
            for num in nums:
                print("target",remainder)
                print("num",num)             
                result=dfs(remainder-num)
                if result!=None:                    
                    combination=[*result,num]                    
                    if shortest_combination==None or len(combination)<len(shortest_combination):                        
                        shortest_combination=combination                    
            return shortest_combination       
        return -1 if dfs(target)==None else len(dfs(target))
    
        
    
s=Solution()
s.coinChange([1,2,5],100)

I print num and remainder, and I see that for some reason remainder never hits 0. Based on DFS, if I keep subtracting 1 from 100 I should be reaching 0, but somehow it does not reach it with any num.

CodePudding user response:

This problem needs to be solved using dynamic programming. Given any value, assume you've already calculated the smallest number of coins to generate 0, ... value - 1, To calculate the smallest number of coins for value, look at the number of coins needed for value - coin1, value - coin2, value - coin3, ..., pick the smallest, and add one.

Actually coding this is something you should do on your own.

CodePudding user response:

Your algorithm is correct, it really does hit 0, but in that case you don't print it (function exits before printing). Adding more debugging you'll see it does reach that base case and backtracks and correctly identifies the sub-solutions.

The problem really is that the tree you are visiting with DFS is exponentially large, whereby you solve the same problem a multitude of times. If you add a few lines of code to implement memoization, you'll see it does the job:

from typing import List

class Solution:
    def coinChange(self, nums: List[int], target: int) -> int:
        memo = {}  # used for memoization
        def dfs(remainder):
            if remainder in memo:  # already solved this problem?
                return memo[remainder]  # then return what we got last time
            if remainder<0:
                return None
            if remainder==0:
                return []         
            shortest_combination=None
            for num in nums:
                result = dfs(remainder-num)
                if result!=None:
                    combination=[*result,num]
                    if shortest_combination==None or len(combination)<len(shortest_combination):
                        shortest_combination=combination                    
            memo[remainder] = shortest_combination  # memoize this solution
            return shortest_combination

        return -1 if dfs(target)==None else len(dfs(target))


s=Solution()
print(s.coinChange([1,2,5],100))  # 20
  • Related