每天一道题-1
在这个题目中,开始思考的方法就是从特殊到普适的过程。
-
暴力求法,直接每一层进行一次对不同面额的硬币进行一次遍历减少,
amount - coin for coins剩余的总数再进行如何进行遍历处理。直到amount = 0得到结果后再比较所需的货币数量 -
由暴力解法,可以更好的想到 BFS 广度优搜索 + 记忆化 也就是看那个分支更快的到达终点。
class Solution { public int coinChange(int[] coins, int amount) { if (amount < 1) { return 0; } return bfs(coins, rem, new int[amount]); } private int bfs(int[] coins, int rem, int[] count) { // 结束标志 if (rem < 0) { return -1; } if (rem == 0) { return 0; } // 检测存放结果的地方是否得到结果 if (count[rem - 1] != 0) { return count[rem - 1]; } int min = Integer.MAX_VALUE; for (int coin : coins) { // 遍历一个状态下减去所有硬币的可能 int res = bfs(coins, rem - coin, count); // 筛选掉无法兑换成功的可能 if (res >= 0 && res < min) { min = 1 + res; } } // 存放每个状态的最优值 count[rem - 1] = (min == Integer.MAX_VALUE) ? -1 : min; return count[rem - 1]; } } -
总结下这个问题,其实是一个优化问题,可以使用 DP 动态规划 的解决方法
class Solution { public int coinChange(int[] coins, int amount) { int max = amount + 1; //作为一个标志位,在最后与amount进行比较判断是否可以兑换成功 int[] dp = new int[max]; Arrays.fill(dp, max); dp[0] = 0; for (int i = 1; i < amount; i ++) { for (int j = 0; j < coins.length; j ++) { // 判断是否有硬币小于当前总数 if (coins[j] <= i) { // 多次比较,得到当前总数的最优解 dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1); } } } // 通过预先放置的值来进行比较,从而得知是否兑换成功 return dp[amount] > amount ? -1 : dp[amount]; } }

浙公网安备 33010602011771号