leetcode刷题日记2020-10-06

134 阅读1分钟

零钱兑换

leetcode-cn.com/problems/co…

思路

常见思路为DP,这里采用DFS + 贪心算法:

  1. 倒排coins数组
  2. 按照DFS遍历所有组合

由于本题极容易超时,因此在遍历时需要进行大量剪枝等等优化:

  1. 按照k = int(remain_amount / reverse_coins[index])计算最多该面值可使用多少硬币,直接从最大值搜索
  2. 如果现有硬币数超过已查询到的最小组合值,则不再继续查找

代码

class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        self.result = float("inf")
        def dfs(reverse_coins, remain_amount, index, count):
            if remain_amount == 0:
                self.result = min(self.result, count)
                return
            if index == len(reverse_coins):
                return
            k = int(remain_amount / reverse_coins[index])
            while k >= 0 and count + k < self.result:
                dfs(reverse_coins, remain_amount - k * reverse_coins[index], index + 1, count + k)
                k -= 1

        if amount == 0:
            return 0
        coins.sort(reverse=True)
        dfs(coins, amount, 0, 0)
        if self.result == float("inf"):
            return -1
        else:
            return self.result