• 零钱兑换(动态规划)


    1、题目:

    leetcode_322_零钱兑换:https://leetcode-cn.com/problems/coin-change/

    给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

    示例 1:

    输入: coins = [1, 2, 5], amount = 11
    输出: 3
    解释: 11 = 5 + 5 + 1
    示例 2:

    输入: coins = [2], amount = 3
    输出: -1

    2、思路:

    求最有解,动态规划解决。

    3、代码:

    解法1:暴力递归,超时,时间复杂度o(n^2)

    class Solution {
        public int coinChange(int[] coins, int amount) {
            if(amount==0) return 0;
            int result = coinChange1(coins, amount);
            if(result==Integer.MAX_VALUE){
                return -1;
            }else{
                return result;
            }
        }
    
        public static int coinChange1(int[] coins, int amount) {
            if (coins == null || amount < 1) {
                return Integer.MAX_VALUE;
            }
            for (int coin : coins) {
                if (coin == amount) {
                    return 1;
                }
            }
            int min = Integer.MAX_VALUE;
            for (int coin : coins) {
                min = Math.min(coinChange1(coins, amount - coin), min);
            }
            if (min == Integer.MAX_VALUE) {
                return Integer.MAX_VALUE;
            } else {
                return min + 1;
            }
        }
    }

    解法2:动态规划

    (1)定义状态:假设dp(n)是凑到n分需要的最少硬币个数

    (2)求递推式:

    如果第 1 次选择了 25 分的硬币,那么 dp(n) = dp(n – 25) + 1

    如果第 1 次选择了 20 分的硬币,那么 dp(n) = dp(n – 20) + 1

    如果第 1 次选择了 5 分的硬币,那么 dp(n) = dp(n – 5) + 1

    如果第 1 次选择了 1 分的硬币,那么 dp(n) = dp(n – 1) + 1

    所以 dp(n) = min { dp(n – 25), dp(n – 20), dp(n – 5), dp(n – 1) } + 1

    初始状态:

    dp[0]=0

    所有dp[i]都初始化为Integer.MAX_VALUE

        public static int coinChange(int[] coins, int amount) {
            if (coins == null || coins.length == 0) {
                return -1;
            }
            int[] dp = new int[amount + 1];
            for (int i = 1; i < amount + 1; i++) {
                int min = Integer.MAX_VALUE;
                for (int j = 0; j < coins.length; j++) {
                    if (i < coins[j] || dp[i - coins[j]] == -1) {
                        continue;
                    }
                    if (i - coins[j] >= 0) {
                        min = Math.min(min, dp[i - coins[j]]);
                    }
                }
                if (min == Integer.MAX_VALUE) {
                    dp[i] = -1;
                } else {
                    dp[i] = min + 1;
                }
            }
            return dp[amount];
        }

    ..

  • 相关阅读:
    Individual Project
    最后的作业
    Reading Task 2 —— by12061154Joy
    Code Review —— by12061154Joy
    Pair Project —— Elevator Scheduler
    《移山之道》Reading Task——by12061154Joy
    Individual Project
    qa_model
    个人阅读作业2
    Personal Reading Assignment 2 -读推荐文章有感以及项目开发目前总结
  • 原文地址:https://www.cnblogs.com/guoyu1/p/13199512.html
Copyright © 2020-2023  润新知