发布于 2016-01-03 21:15:54 | 240 次阅读 | 评论: 0 | 来源: PHPERZ

这里有新鲜出炉的精品教程,程序狗速度看过来!

Leetcode 在线编程网站

leetcode 是一个美国的在线编程网站,上面主要收集了各大IT公司的笔试面试题,对于应届毕业生找工作是一个不可多得的好帮手。


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.

分析

典型的DP问题。注意这里的硬币是可以无限使用的,另外注意下无法兑换返回-1的处理。
很多人首先想到的是Greedy,即总是取最大的硬币,不够再取小的,这种方法得到的结果是不能保证最小硬币数量的, 比如输入是[1, 3, 5, 6], 8, Greedy得到结果是3(6 + 1 + 1),而正确结果是2(3 + 5)

这道题要求是返回硬币个数,显然Follow up可以是在最少硬币的情况下,返回具体的硬币值

我能想到的比较直接的方法就是用一个map对于每个可以组合的amount用一个List存对应的硬币组合,然后同样是DP的方法找到最小硬币组合,更新组合。

复杂度

time: O(n*m), space: O(n), n表示amount,m表示硬币个数。

代码

public class Solution {
    public int coinChange(int[] coins, int amount) {
        // 无效输入的处理
        if (amount == 0)
            return 0;
        if (coins == null || coins.length == 0)
            return -1;
            
        int[] dp = new int[amount + 1];
        for (int i = 1; i <= amount; i++) {
            int min = Integer.MAX_VALUE;
            for (int j = 0; j < coins.length; j++) {
                if (i >= coins[j] && dp[i - coins[j]] != -1)
                    min = Math.min(min, dp[i - coins[j]] + 1);
            }
            
            // 根据min的值判断是否能兑换
            dp[i] = min == Integer.MAX_VALUE ? -1 : min;
        }
        return dp[amount];
    }
}


最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务