当前位置: 首页 > web >正文

代码随想录算法训练营Day37

完全背包
力扣517.零钱兑换【medium】
力扣518.零钱兑换【medium】
力扣377.组合总和Ⅳ【meidum】

一、完全背包

  • 有 n 种物品,可以重复使用
  • 在转为一维数组时:一般是先物品后背包,物品是正序的,背包也是正序
  • 在只用一个一维数组的情况下,要注意转移来源
      1. 不能被覆盖
      1. 必须已经计算出来。
  • 按照这个要求,正序遍历会导致 0-1 背包状态被覆盖,而完全背包则是正确的(转移来源被计算出来,且不存在被覆盖的问题);逆序遍历对于 0-1 背包是正确的(转移来源是上一行的,早就被计算出来了且没有被覆盖),而完全背包则不行(转移来源没有被计算出来)。
  • 01背包 在转为i一维数组:背包是逆序的,因为如果是正序,会出现重复计数,转移来源是上一行的
  • 完全背包 则需要叠加左边的状态

二、力扣322.零钱兑换【medium】

题目链接:力扣322.零钱兑换
在这里插入图片描述
视频链接:代码随想录
题解链接:灵茶山艾府

1、思路

  • f [ i ] [ c ] f[i][c] f[i][c]表示在 c o i n s [ 0 ] coins[0] coins[0] c o i n s [ i ] coins[i] coins[i] 中选出最少的硬币个数凑出金额 c c c

2、代码

记忆化搜索
  • 时间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
  • 空间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
class Solution:def coinChange(self, coins: List[int], amount: int) -> int:n = len(coins)@cachedef dfs(i:int, c:int) -> int:if i < 0:return 0 if c == 0 else infif c < coins[i]:return dfs(i - 1, c)return min(dfs(i - 1, c), dfs(i, c - coins[i]) + 1)ans = dfs(n - 1, amount)return ans if ans < inf else -1
翻译递推:动态规划-二维数组
  • 时间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
  • 空间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
class Solution:def coinChange(self, coins: List[int], amount: int) -> int:n = len(coins)f = [[inf] * (amount + 1) for _ in range(n + 1)]f[0][0] = 0for i, x in enumerate(coins):for c in range(amount + 1):if c < x:f[i + 1][c] = f[i][c]else:f[i + 1][c] = min(f[i][c], f[i + 1][c - x] + 1)ans = f[n][amount]return ans if ans < inf else -1
空间优化:动态规划 - 一维数组
  • 时间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
  • 空间复杂度: O ( a m o u n t ) O( amount) O(amount)
class Solution:def coinChange(self, coins: List[int], amount: int) -> int:n = len(coins)f = [0] + [inf] * (amount)for x in coins:for c in range(x, amount + 1):f[c] = min(f[c], f[c - x] + 1)ans = f[amount]return ans if ans < inf else -1

三、力扣518.零钱兑换【medium】

题目链接:力扣518.零钱兑换
在这里插入图片描述
视频链接:代码随想录
题解链接:灵茶山艾府

1、思路

  • 与上题一致,这边问的是方法数
  • 所以这边要小心状态方程 和 初值的设置!
  • f [ i ] [ c ] f[i][c] f[i][c]表示在 c o i n s [ 0 ] coins[0] coins[0] c o i n s [ i ] coins[i] coins[i] 中选出硬币个数可以凑出金额 c c c 的方法数!

2、代码

记忆化搜索
  • 时间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
  • 空间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
class Solution:def change(self, amount: int, coins: List[int]) -> int:n = len(coins)@cachedef dfs(i:int, c:int) -> int:if i < 0:return 1 if c == 0 else 0if c < coins[i]:return dfs(i - 1,c)return dfs(i - 1, c) + dfs(i, c - coins[i]) return dfs(n - 1, amount)
翻译递推:动态规划-二维数组
  • 时间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
  • 空间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
class Solution:def change(self, amount: int, coins: List[int]) -> int:n = len(coins)f = [[0] * (amount + 1) for _ in range( n + 1)]f[0][0] = 1for i, x in enumerate(coins):for c in range(amount + 1):if c < x:f[i + 1][c] = f[i][c]else:f[i + 1][c] = f[i][c] + f[i + 1][c - x]return f[n][amount]
空间优化:动态规划 - 一维数组
  • 时间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount)
  • 空间复杂度: O ( a m o u n t ) O( amount) O(amount)
class Solution:def change(self, amount: int, coins: List[int]) -> int:n = len(coins)f = [1] + [0] * (amount)for x in coins:for c in range(x, amount + 1):f[c] = f[c] + f[c -x]return f[amount]

四、力扣377.组合总和Ⅳ【meidum】

题目链接:力扣377.组合总和Ⅳ
在这里插入图片描述
视频链接:代码随想录
题解链接:灵茶山艾府

1、思路

  • 这道题请注意用例!

  • 是排列,不是组合!

  • 排列的遍历顺序:先背包再物品

  • 组合的遍历顺序:先物品再背包

  • 回溯——本质上是爬楼梯:最后一爬有 n = len(nums) 种选择, 所以:

    d f s ( i ) = s u m ( d f s ( i − x ) f o r x i n n u m s i f x < = i ) dfs(i) = sum(dfs(i - x) for x in nums if x <= i) dfs(i)=sum(dfs(ix)forxinnumsifx<=i)

  • 时间复杂度: O ( n ∗ t a r g e t ) O(n * target) O(ntarget)

  • 空间复杂度: O ( n ∗ t a r g e t ) O(n * target) O(ntarget);优化后: O ( t a r g e t ) O(target) O(target)

2、代码

class Solution:def combinationSum4(self, nums: List[int], target: int) -> int:@cachedef dfs(i:int):if i == 0: # 爬完了return 1 return sum (dfs(i - x) for x in nums if x <= i) # 枚举所有可以爬的台阶数return dfs(target)
class Solution:def combinationSum4(self, nums: List[int], target: int) -> int:f = [1] + [0] * targetfor i in range(target + 1):for x in nums:if x <= i:f[i] += f[i - x]return f[target]

http://www.xdnf.cn/news/2541.html

相关文章:

  • Diamond软件的使用--(6)访问FPGA的专用SPI接口
  • 关于百度模型迭代个人见解:技术竞速下的应用价值守恒定律
  • Vue3项目目录结构规范建议
  • 【测控系统】测控仪器技术概述与专业选择
  • 【项目实训个人博客】multi-agent调研(1)
  • XMOS直播声卡——可支持实时音频DSP处理的低延迟音频方案
  • Web前渗透
  • JavaScript基础(七)之web APIs
  • 开源项目实战学习之YOLO11:ultralytics-cfg-datasets-VOC、xView.yaml文件(八)
  • 设计模式--桥接模式详解
  • 【C++贪心 滑动窗口】P7990 [USACO21DEC] Closest Cow Wins S|省选-
  • UE5 在旋转A的基础上执行旋转B
  • 复杂背景下无人机影像小目标检测:MPE-YOLO抗遮挡与抗背景干扰设计
  • 深度学习算法:开启智能时代的钥匙
  • FastAPI中的依赖注入详解与示例
  • 假设检验学习总结
  • SQL优化,关联查询非常慢,前台页面控件卡顿
  • 使用 Playwright 构建高效爬虫:原理、实战与最佳实践
  • 大模型应用实战:深入理解模型上下文协议 MCP
  • Linux-UDP套接字编程
  • 小结: DHCP
  • 【SpringMVC】概念引入与连接
  • Spark-Streaming2
  • 深入解析Vue.js:构建现代Web应用的高效之道
  • BIOES 标签的含义
  • 三分钟音乐社:8、构建(自然)大调的音阶
  • 【嵌入式系统设计师(软考中级)】第二章:嵌入式系统硬件基础知识——④定时器计数器和系统总线及通信接口
  • 全面解析Java(上)------多线程编程:从线程生命周期到并发机制的深度剖析与实践指南
  • 组件的基本知识
  • 力扣hot100,739每日温度(单调栈)详解