【Golang】LeetCode 322. 零钱兑换

322. 零钱兑换

题目描述

思路

「零钱兑换」这道题目的解决思路几乎与「完全平方数」相同。主要的区别在于,「完全平方数」要求我们求表示一个数值最少需要多少个"完全平方数",相当于硬币的面额就是自然数的"完全平方数"。而「零钱兑换」这道题预先给定了我们可以使用的零钱的面额。

我们使用动态规划来解决这道题,首先初始化一个数组dp,它的长度是amount + 1,用来表示数值为i的面额最少需要多少个零钱来凑出。我们初始化i == 0之外每一个dp[i]的值为amount + 1,经过对dp数组的维护之后,如果dp[i] == amount + 1,就代表这个面额无法通过当前给定的零钱的面额表示出来(比如i == 3,但是只有面额2, 4, 6, 8可用)。基于解决「完全平方数」的经验,我们不难直接推导出维护dp数组的状态转移方程,那就是dp[i] = min(dp[i - coins[j]] + 1, dp[i])。我们使用两层循环来对dp进行维护,i遍历的是当前要表示的面额的数值,在最外层循环;j是第二层循环,用于对给定的零钱的面额值进行遍历。只有当i >= coins[j]的时候,才需要对dp进行维护。

需要注意的点是,在初始化dp[i] = amount + 1时,一定不能设置dp[0]的值也是amount + 1。对于面额0,从dp数组的表示意义上来说,它的值就应该设置为0,因为面额为0的状态不需要任何零钱来凑出。

基于以上思路和状态转移方程,我们就可以开始解题了。

Golang 题解

go 复制代码
func coinChange(coins []int, amount int) int {
    n := len(coins)
    dp := make([]int, amount + 1)
    for i := 1; i <= amount; i ++ {
        dp[i] = amount + 1
    }

    for i := 1; i <= amount; i ++ {
        for j := 0; j < n; j ++ {
            if i >= coins[j] {
                dp[i] = min(dp[i - coins[j]] + 1, dp[i])
            }
        }
    }

    if dp[amount] == amount + 1 {
        return -1
    }
    return dp[amount]
}
相关推荐
Tisfy21 分钟前
LeetCode 2333.最小差值平方和:排序 + 数学计算(不用二分)
数学·算法·leetcode·题解·贪心·排序
aqiu11111125 分钟前
【C++算法打怪专栏】LeetCode 217. 存在重复元素(解法总结)
c++·算法·leetcode
yi0112 小时前
DAY28: LeetCode 111. 二叉树的最小深度
人工智能·笔记·python·算法·leetcode·二叉树·递归
wuyk5552 小时前
27.LeetCode 2265. 统计值等于子树平均值的节点数 —— 后序遍历实战
stm32·单片机·嵌入式硬件·算法
xiangyun612 小时前
C++ list 模拟实现(二):const迭代器与反向迭代器,模板的黑魔法
开发语言·数据库·c++·算法·stl·list
xxwl5852 小时前
三、区域赛算法模版第三章---字符串相关算法
笔记·学习·算法
信奥卷王2 小时前
[GESP202509 六级] 划分字符串(含视频)
数据结构·算法
酒醉的胡铁3 小时前
相似度搜索的常见算法
算法·ai
局部有解3 小时前
Leetcode Hot100 - 最长连续序列
算法·leetcode·职场和发展
行者全栈架构师3 小时前
给开源 Rust 工具加一个新检查项,TRAE 帮我从想法跑到构建产物:全链路实战
前端·算法·架构