leetcode322. Coin Change

题目要求

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

Example 1:
coins = [1, 2, 5], amount = 11
return 3 (11 = 5 + 5 + 1)

Example 2:
coins = [2], amount = 3
return -1.

Note:
You may assume that you have an infinite number of each kind of coin.

这里模拟实现了一个换钱算法。传入的参数为手上有的纸币的面额以及希望兑换的面额。这里假设纸币的数量是无穷的。

这题本质上考察的是动态规划思想。这里有两种动态规划的方法,分别从递归和非递归的角度解决这个问题。具体的情况还是要看数据的分布情况来确定选择哪种方法。

非递归

这里我们新建一个临时数组result,下标i上的值来存储用当前手上的纸币兑换面额i时所需要的最少的纸币数量。这样,假设有一个纸币数组[coin[0], coint[1], ..., coin[k]],我们需要计算兑换面额i所需要的最小数量的纸币,那么只需要比较[result[i-coin[0]], result[i-coin[1]], result[i-coin[2]] ... , result[i-coint[k]]]即可。这里需要考虑一些越界情况比如手上纸币面额比需兑换面额大。还有可能result[i-coin[t]]是无法兑换的。

    public int coinChange(int[] coins, int amount) {
        if(amount==0) return 0;
        Arrays.sort(coins);
        if(coins==null || coins.length==0 || amount < coins[0]) return -1;
        int[] result = new int[amount+1];
        for(int i = coins[0] ; i<=amount; i++){
            int tmp = Integer.MAX_VALUE;
            for(int j = 0 ; j<coins.length ; j++){
                int remain = i-coins[j];
                if(remain < 0) continue;
                else if(remain==0 || result[remain]!=0){
                    tmp = Math.min(tmp, result[remain]+1);
                }
            }
            result[i] = tmp==Integer.MAX_VALUE ? 0 : tmp;
        }
        return result[amount] == 0 ? -1 : result[amount];
    }

递归

这里需要注意的是,用int数组作为一个缓存来减少重复计算的损耗。其实这里的代码还是可以继续优化的。

    private int[] cache;
    public int coinChange2(int[] coins, int amount){
        cache = new int[amount];
        return coinChangeRecursive(coins, amount);
    }
    
    public int coinChangeRecursive(int[] coins, int amount){
        if(amount<0) return -1;
        if(amount==0) return 0;
        if(cache[amount-1] != 0) return cache[amount-1];
        int min = Integer.MAX_VALUE;
        for(int coin : coins){
            int res = coinChangeRecursive(coins, amount-coin);
            if(res>=0 && res<min){
                min = res+1;
            }
        }
        cache[amount-1] = min==Integer.MAX_VALUE ? -1 : min;
        return cache[amount-1];
    }

clipboard.png
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值