【Leetcode】322. Coin Change

class Solution1(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        dp = [float("inf")] * (amount + 1)
        dp[0] = 0
        for i in range(1, len(dp)):
            for coin in coins:
                if i - coin >= 0 :
                    dp[i] = min(dp[i-coin] + 1, dp[i])
        return dp[-1] if dp[-1] != float("inf") else -1

class Solution2(object):
    """
    this recursion from bottom to the top, and return result in the top
    we can optimize by store the intermediate result in dict
    """
    def coinChange(self, coins, amount):
        self.dict = {}
        result = self.DFS(coins, amount)
        return result if result != float("inf") else -1

    def DFS(self, coins, amount):
        if amount == 0: return 0
        if amount not in self.dict:
            miner = min([self.DFS(coins, amount -coin) for coin in coins if amount - coin >= 0] + [float("inf")]) + 1
            self.dict[amount] = miner
        return self.dict[amount]

class Solution3(object):
    """
    this recursion from top to bottom and return result in the bottom
    and it's hard to store the intermediate result
    """
    def coinChange(self, coins, amount):
        self.res = float("inf")
        self.DFS(coins, amount, 0)
        return self.res if self.res != float("inf") else -1

    def DFS(self, coins, amount, count):
        if amount == 0:
            self.res = min(self.res, count)
        for coin in coins:
            if amount -  coin >= 0:
                self.DFS(coins, amount - coin, count + 1)

class Solution4(object):
    """
    optimize recursion from top to bottom, and use coin from max to min to prue the repeating path
    faster than 97.16%
    """
    def coinChange(self, coins, amount):
        # must sort
        coins.sort(reverse=True)
        self.res = float("inf")
        for i in range(len(coins)):
            self.DFS(i, coins, amount, 0)
        return self.res if self.res != float("inf") else -1

    def DFS(self, index, coins, amount, count):
        if amount == 0 :
            self.res = min(self.res, count)
        for i in range(index, len(coins)):
            if amount - coins[i] >= 0 and amount < coins[i] * (self.res - count) : #prune here, precondition is sort reverse (use max coin can't relaize the the min either)
                self.DFS(i, coins, amount - coins[i], count+1)

相关文章: