开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情
作者: 千石
支持:点赞、收藏、评论
欢迎各位在评论区交流
前言
本文内容来自我平时学习的一些积累,如有错误,还请指正
在题目实战部分,我将代码实现和代码解释设置在了解题思路的下方,方便各位作为参考刷题
一些话
本文内容来自我平时学习的一些积累,如有错误,还请指正
在题目实战部分,我将代码实现和代码解释设置在了解题思路的下方,方便各位作为参考刷题
题目练习步骤:
- 给自己10分钟,读题并思考解题思路
- 有了思路以后开始写代码,如果在上一步骤中没有思路则停止思考并且看该题题解
- 在看懂题解(暂时没看懂也没关系)的思路后,背诵默写题解,直至能熟练写出来
- 隔一段时间,再次尝试写这道题目
前置知识
贪心算法定义
顾名思义就是说,一种在每一步选择中都采取在当下状态下最好,最优的选择希望导致结果是全局最好或者最优的。
最后是希望结局导致全局最好或者最优,采取的办法就是在当下选择最好或者最优的,但当下最好/最优的并不一定是全局最好最优的。
贪心算法与回溯、动态规划的不同点
| 算法 | 区别 |
|---|---|
| 贪心 | 当下做局部最优判断 |
| 回溯 | 能够回退 |
| 动态规划 | 最优判断 + 回退 |
贪心法主要解决的是一些最优化问题最小生成树、求哈夫曼编码等),对于工程或者生活中的问题,贪心法一般来说不能得出我们想要的答案
实战
题目:322. 零钱兑换 - 力扣(LeetCode)
思路:
- 定义一个数组
dp,其中dp[i]表示凑成总金额为i所需的最少的硬币个数。 - 初始化
dp[0] = 0,因为凑成总金额为0时不需要任何硬币。 - 遍历每一个硬币
coin,如果coin的面值小于等于总金额i,则更新dp[i]的值,使其成为dp[i-coin]+1和当前的dp[i]中的较小值。这里,dp[i-coin]+1表示加上一枚硬币coin后凑成总金额为i的最小硬币数。 - 最后,如果
dp[amount]的值不是无穷大,则返回dp[amount],否则返回-1。
代码实现:
def coinChange(coins, amount):
dp = [float('inf')] * (amount + 1)
dp[0] = 0
for i in range(1, amount + 1):
for coin in coins:
if coin <= i:
dp[i] = min(dp[i], dp[i - coin] + 1)
return dp[amount] if dp[amount] != float('inf') else -1
时间复杂度分析:
设数组 `coins` 的长度为 `n`,则时间复杂度为 $O(n \times amount)$。