LeetCode 322. Coin Change 零钱兑换 (DP)

https://leetcode.com/problems/coin-change/description/

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例 1:

输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1

示例 2:

输入: coins = [2], amount = 3
输出: -1

说明:
你可以认为每种硬币的数量是无限的。

题解:
贪心?
反例:1,5,7 凑10,贪心要1个7和3个1,而最优解是2个5.

动态规划:
确定状态:f(x)表示凑足x的钱最少的硬币数
起始状态:f(0)=0
终止状态:f(amount)
决策:要想使本f(x)最小,每次所有钱币,取最小的 f(x-ci)
无后效性:收益只取决与当前状态和决策
收益表示:f(x)=min{ f(x-ci) }+1 , i=1,2,3…n

递推:

class Solution {
    public int coinChange(int[] coins, int amount) {
        if (amount < 0 || coins.length == 0) {
            return -1;
        }
        int[] f = new int[amount + 1];// 凑i元最少需要的硬币数
        f[0] = 0;
        for (int i = 1; i <= amount; i++) {
            int min = Integer.MAX_VALUE;
            for (int c : coins) {
                int j = i - c;// 记录用掉这个钱币,剩余的钱数
                if (j >= 0 && f[j] != -1) {// j元也能凑成功
                    min = Math.min(min, f[j]);
                }
                f[i] = min == Integer.MAX_VALUE ? -1 : min + 1;//min == Integer.MAX_VALUE 说明花掉这个硬币,不能凑成功,如果凑成功,硬币数+1
            }
        }
        return f[amount];
    }

}

递归:(超时)

class Solution {
    public int coinChange(int[] coins, int amount) {
        cache.clear();
        return robot(coins, amount);
    }

    public static Map<Integer,Integer> cache=new HashMap<Integer,Integer>();
    private int robot(int[] coins, int amount) {// 凑amount元最少需要的硬币数
        if (amount == 0) {
            return 0;
        }
        if (amount < 0) {
            return -1;
        }
        if(cache.containsKey(amount)){
            return cache.get(amount);
        }
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < coins.length; i++) {
            int next = robot(coins, amount - coins[i]);
            if (next == -1) {//使用该钱币不能构成这个钱数
                continue;
            }
            int num = 1 + next;//使用是个钱币
            if (num < min) {//更新最小钱币数
                min = num;
                cache.put(amount, min);
            }
        }
        if (min == Integer.MAX_VALUE) {//不能凑成
            return -1;
        } else {
            return min;
        }
    }

}

猜你喜欢

转载自blog.csdn.net/zxm1306192988/article/details/80671599