【举一反三】力扣刷题-零钱兑换(Go 实现)

快速通道

322. 零钱兑换
518. 零钱兑换 II

前言

这个月是动态规划月呀,动态规划的题目核心就是找到状态转移方程。零钱兑换这个系列是很经典的背包题,就是总容量,然后往里边放固定大小的物品,有的是返回方案数,有的是返回最少物品的个数。

一定要看

一篇文章吃透背包问题!(细致引入+解题模板+例题分析+代码呈现)

322. 零钱兑换

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

你可以认为每种硬币的数量是无限的。

来源:力扣(LeetCode)

理解

这种题目乍一看很像贪心算法题,先取大的放,不过不行再放小的。不过如果不能正好放下的话,就需要再取小一点的,然后再放重复。这样就类似于回溯算法了,不过这样做执行会超时。
既然超时了,一般回溯(DFS)的做法就是记忆化存储,就是疯狂剪枝。
不过这边就不这样做了,熟悉这种题型的就能判断该题就是背包问题中返回最小物品的个数。

解题

动态规划题型一般都需要一个数组来存储前面的数,然后通过状态转移方程来获取下一个数

func coinChange(coins []int, amount int) int {
    // 背包问题·
    dp := make([]int, amount+1)
    
    for i:=1; i<=amount; i++ {
        dp[i] = amount + 1
        for _, coin := range coins {
            if i >= coin && dp[i - coin] + 1 < dp[i] {
                dp[i] = dp[i - coin] + 1 
            }
        }
    }
    if dp[amount] == amount + 1 {
        return -1
    }
    return dp[amount]
}
518. 零钱兑换 II

给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。

请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。

假设每一种面额的硬币有无限个。

题目数据保证结果符合 32 位带符号整数。

来源:力扣(LeetCode)

理解

这一题跟之前做过的 377. 组合总和 Ⅳ 很相似 -->
【举一反三】力扣刷题-组合总和(Python 实现)当时这边还是用的回溯+剪枝做的,回头再看看。
说回这一题,这一题也是求组合数,只不过这一题不能有重复的组合,或者说那一题是有序的,所以可以存在重复的组合。

解题

如何保证没有重复的组合呢,那就想办法让组合是单调递增即可,这个地方实现起来稍微麻烦,我要保证我的下一个数不比前一个数小,那我应该让小的数先排。 看实现,先循环的coins,然后再维护dp数组,这个地方很巧妙。开头我放一下力扣上一位大佬写的总结,这位大佬总结了各种背包问题。

func change(amount int, coins []int) int {
    // 动态规划
    dp := make([]int, amount + 1)
    dp[0] = 1
    for _,coin := range coins {
        for i:=coin;i<=amount;i++ {
            dp[i] += dp[i - coin]
        }
    }
    return dp[amount]
}
小试牛刀

279. 完全平方数

讲解:

【知识迁移】力扣刷题- 完全平方数(Go 实现)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,关于力扣刷C++常用操作,我可以给你一些常见的操作和技巧: 1. 使用 STL 容器和算法库:STL(Standard Template Library)是 C++ 标准库中的一个重要组成部分,包含了许多常用的容器和算法。在力扣刷中,使用 STL 可以大大提高代码的效率和可读性。例如,vector 可以用来存储动态数组,sort 可以用来排序等等。 2. 使用 auto 关键字:auto 关键字可以自动推导变量类型,可以减少代码量和提高可读性。例如,auto x = 1; 可以自动推导出 x 的类型为 int。 3. 使用 lambda 表达式:lambda 表达式是 C++11 中引入的一种匿名函数,可以方便地定义一些简单的函数对象。在力扣刷中,使用 lambda 表达式可以简化代码,例如在 sort 函数中自定义比较函数。 4. 使用位运算:位运算是一种高效的运算方式,在力扣刷中经常会用到。例如,左移运算符 << 可以用来计算 2 的幂次方,右移运算符 >> 可以用来除以 2 等等。 5. 使用递归:递归是一种常见的算法思想,在力扣刷中也经常会用到。例如,二叉树的遍历、链表的反转等等。 6. 使用 STL 中的 priority_queue:priority_queue 是 STL 中的一个容器,可以用来实现堆。在力扣刷中,使用 priority_queue 可以方便地实现一些需要维护最大值或最小值的算法。 7. 使用 STL 中的 unordered_map:unordered_map 是 STL 中的一个容器,可以用来实现哈希表。在力扣刷中,使用 unordered_map 可以方便地实现一些需要快速查找和插入的算法。 8. 使用 STL 中的 string:string 是 STL 中的一个容器,可以用来存储字符串。在力扣刷中,使用 string 可以方便地处理字符串相关的问。 9. 注意边界条件:在力扣刷中,边界条件往往是解决问的关键。需要仔细分析目,考虑各种边界情况,避免出现错误。 10. 注意时间复杂度:在力扣刷中,时间复杂度往往是评判代码优劣的重要指标。需要仔细分析算法的时间复杂度,并尽可能优化代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值