322. 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:

Input: coins = [1, 2, 5], amount = 11
Output: 3 
Explanation: 11 = 5 + 5 + 1

Example 2:

Input: coins = [2], amount = 3
Output: -1

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

class Solution {
    public int coinChange(int[] coins, int amount) {
        int res = -1;
        List<List<Integer>> all = new ArrayList();
        List<Integer> path = new ArrayList();
        help(all, path, coins, amount);
        int le = all.size();
        if(le == 0) return -1;
        else{
            res = all.get(0).size();
            for(int i = 1; i < le; i++){
                res = Math.min(res, all.get(i).size());
            }
        }
        return res;
    }
    public void help(List<List<Integer>> all, List<Integer> path, int[] coins, int remains){
        if(remains == 0){
            all.add(new ArrayList(path));
        }
        else if(remains < 0) return;
        else{
            for(int i = 0; i < coins.length; i++){
                path.add(coins[i]);
                help(all, path, coins, remains - coins[i]);
                path.remove(path.size() - 1);
            }  
        }
    }
}

555,写的dfs通过了15个testcase就说time limit error了草。

 

 Recursive 应该是这样的,求F(6),就要求F(5), F(4), F(3),以此类推,不过这样的topdown答案不够直观。饭而bottomup更好

3. bottom up

a。先创造dp数组,除dp【0】赋0外,其他赋值amount + 1即可,后面判断最终条件如果值没有更新会直接爆掉,返回-1。

b。然后amount从1开始到amount,内循环就循环coins,如果coins【j】 <= 当前amount i说明至少可以用这个coin一次,否则比如coin = 3,amount = 2就不行。

c。最终判断dp[ amount]是否是初始值,如果是就返回-1,否则就是答案。

 

 


class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount + 1];//容量为amount的背包最少要装多少硬币
        Arrays.fill(dp, amount + 1);
        dp[0] = 0;
        for(int j = 0; j < coins.length; j++) {//对应i👈1 to N
            for(int i = 1; i <= amount; i++)
             {
                if(i >= coins[j]) dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
            }
        }
        return dp[amount] > amount ? -1 : dp[amount];
    }
}

完全背包问题,不同的是不用算最大值,要算的只是选择硬币的最小数量

 

 

 

 背包容量为V,共有N个物品,每个物品重wi,价值vi

posted @ 2019-09-28 04:57  Schwifty  阅读(158)  评论(0编辑  收藏  举报