LeetCode——零钱兑换

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

示例 1:

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

输入: coins = [2], amount = 3
输出: -1
说明:
你可以认为每种硬币的数量是无限的。

A:
第一反应是回溯我也是没谁了……然后内存就限制了我。

    public int coinChange(int[] coins, int amount) {
        if (amount == 0 || coins.length == 0)
            return 0;
        int count = 0;
        ArrayList<Integer> array = new ArrayList<>();
        coin(coins, amount, count, array);
        if (array.isEmpty())
            return -1;
        int min = Integer.MAX_VALUE;
        for (Integer i : array)
            min = Math.min(min, i);
        return min;
    }

    private void coin(int[] coins, int amount, int count, ArrayList<Integer> array) {
        if (amount == 0) {
            array.add(count);
            return;
        }
        for (Integer i : coins) {
            if (amount >= i) {
                amount -= i;
                count++;
                coin(coins, amount, count, array);
                count--;
                amount += i;
            }
        }
    }

好吧,老老实实用动态规划dp

n=0:dp[n]=0;
n<0:dp[n]=-1;
n>0:if dp[n-coin]!=-1 dp[n]=min(dp[n-coin]+1)

public int coinChange(int[] coins, int amount) {
        if (coins.length == 0 || amount == 0)
            return -1;
        int[] array = new int[amount + 1];
        Arrays.fill(array, -1);
        array[0] = 0;
        for (int i = 1; i <= amount; i++) {
            int min = Integer.MAX_VALUE;
            for (Integer in : coins) {
                if (i - in >= 0 && array[i - in] != -1) {
                    min = Math.min(min, array[i - in] + 1);
                }
                if (min != Integer.MAX_VALUE)
                    array[i] = min;
            }
        }
        return array[amount];
    }
posted @ 2020-03-27 12:03  Shaw_喆宇  阅读(208)  评论(0编辑  收藏  举报