Leetcode 322 零钱兑换

题意理解

        给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

        计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

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

        coins表示不同值得元素,有无限个,目标是使用元素凑出目标值最少需要多少个硬币

        这是一个完全背包问题,但不是一个纯背包问题。因为这里问的不是背包里物品的重量或价值,而是最少用多少个硬币。

解题思路

        根据题意,我们可以得到

        dp[j]表示凑出j最少使用dp[j]个硬币

        递推公式:dp[j]=min(dp[j-coins[i]],dp[j])

        从组合数和排列数来看,无论是组合数还是排列数其最少硬币数都是一样的,所以双for循环的顺序是可以颠倒的,对结果无影响。

        由于物体可以重复取用,所以对于背包的遍历选择正序遍历

1.解题

public int coinChange(int[] coins, int amount) {
        int[] dp=new int[amount+1];
        Arrays.fill(dp,Integer.MAX_VALUE);
        dp[0]=0;
        for(int i=0;i<coins.length;i++){//遍历硬币
            for(int j=1;j<=amount;j++){//遍历背包
                if(coins[i]<=j){
                    if(Integer.compare(Integer.MAX_VALUE,dp[j-coins[i]])!=0)
                        dp[j]= Math.min(dp[j-coins[i]]+1,dp[j]);
                }
            }
        }
        return Integer.compare(Integer.MAX_VALUE,dp[amount])==0?-1:dp[amount];
    }

2.分析

时间复杂度:O(n^2)

空间复杂度:O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值