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

leetCode 322.零钱兑换 完全背包 + 动态规划 + 记忆化搜索 + 递推 + 空间优化 + 画递归树

关于此题我的往期文章LeetCode 322.零钱兑换 完全背包 + 动态规划_呵呵哒( ̄▽ ̄)"的博客-CSDN博客icon-default.png?t=N7T8https://heheda.blog.csdn.net/article/details/133386579看本期文章时,可以先回顾一下动态规划入门知识完全背包理论和实战

0-1背包 完全背包 + 至多/恰好/至少 + 空间优化 + 常见变形题(实战力扣题)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_41987016/article/details/134210521?spm=1001.2014.3001.5501leetCode 198.打家劫舍 动态规划入门:从记忆化搜索到递推-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_41987016/article/details/134179583?spm=1001.2014.3001.5501给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。你可以认为每种硬币的数量是无限的


最优的子结构性质,这是解决动态规划问题的关键。最优解可以从其子问题的最优解构造出来。如何将问题分解成子问题?

(1)递归

class Solution {
public:int coinChange(vector<int>& coins, int amount) {int n = coins.size();function<int(int,int)> dfs=[&](int i,int c) -> int {if(i < 0) {if(c == 0) return 0;else return INT_MAX/2;// 除 2 是防止下面 + 1 溢出}if(c < coins[i]) return dfs(i-1,c);return min(dfs(i-1,c),dfs(i,c-coins[i])+1);     };int ans = dfs(n-1,amount);return ans<INT_MAX/2?ans:-1;}
};

在上面的递归树中,可以看到有许多子问题被多次计算。例如,F(1)被计算了13次。为了避免重复的计算,可以将每个子问题的答案存在一个数组中进行记忆化,如果下次还要计算这个问题的值直接从数组中取出返回即可,这样能保证每个子问题最多只被计算一次。我们接着往下看~

(2)递归搜索 + 保存计算结果 = 记忆化搜索

class Solution {
public:// 记忆化搜索int coinChange(vector<int>& coins, int amount) {int n = coins.size(),memo[n+1][amount+1];memset(memo,-1,sizeof(memo));function<int(int,int)> dfs=[&](int i,int c) -> int {if(i < 0) {if(c == 0) return 0;else return INT_MAX/2;// 除 2 是防止下面 + 1 溢出}int& res = memo[i][c];if(res != -1) return res;if(c < coins[i]) return res=dfs(i-1,c);return res=min(dfs(i-1,c),dfs(i,c-coins[i])+1);     };int ans = dfs(n-1,amount);return ans<INT_MAX/2?ans:-1;}
};

  • 时间复杂度:O(n * amount)
  • 空间复杂度:O(n * amount)

(3)1:1 翻译成递推

class Solution {
public:// 1:1 翻译成递推int coinChange(vector<int>& coins, int amount) {int n = coins.size(),f[n+1][amount+1];memset(f,0x3f,sizeof(f));f[0][0]=0;for(int i=0;i<n;i++) {for(int c=0;c<=amount;c++) {if(c<coins[i]) f[i+1][c] = f[i][c];else f[i+1][c] = min(f[i][c],f[i+1][c-coins[i]]+1); }}int ans = f[n][amount];return ans<0x3f3f3f3f?ans:-1;}
};
  • 时间复杂度:O(n * amount)
  • 空间复杂度:O(n * amount)

 (4)空间优化:两个数组(滚动数组)

class Solution {
public:// 空间优化:两个数组(滚动数组)int coinChange(vector<int>& coins, int amount) {int n = coins.size(),f[2][amount+1];memset(f,0x3f,sizeof(f));f[0][0]=0;for(int i=0;i<n;i++) {for(int c=0;c<=amount;c++) {if(c<coins[i]) f[(i+1)%2][c] = f[i%2][c];else f[(i+1)%2][c] = min(f[i%2][c],f[(i+1)%2][c-coins[i]]+1); }}int ans = f[n%2][amount];return ans<0x3f3f3f3f?ans:-1;}
};
  • 时间复杂度:O(n * amount)
  • 空间复杂度:O(amount)

(5)空间优化:一个数组

class Solution {
public:// 空间优化:两个数组(滚动数组)int coinChange(vector<int>& coins, int amount) {int n = coins.size(),f[amount+1];memset(f,0x3f,sizeof(f));f[0]=0;for(int i=0;i<n;i++) {for(int c=coins[i];c<=amount;c++) {f[c] = min(f[c],f[c-coins[i]]+1); }}int ans = f[amount];return ans<0x3f3f3f3f?ans:-1;}
};
  • 时间复杂度:O(n * amount)
  • 空间复杂度:O(amount)

参考和推荐文章:
322. 零钱兑换 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/coin-change/solutions/132979/322-ling-qian-dui-huan-by-leetcode-solution/

相关文章:

  • 基于STM32CubeMX和keil采用USART/UART实现非中断以及中断方式数据回环测试借助CH340以及XCOM
  • Docker学习——③
  • 【Redis】的简介和安装配置(Linux和windows)及操作命令
  • Hive 解析 JSON 字符串数据的实现方式
  • Golang源码分析之golang/sync之singleflight
  • 【Java初阶练习题】-- 数组练习题
  • Qt界面美化之Qt Style Sheets
  • Ansible自动化安装部署及使用
  • 单链表基本操作的实现,初始化,头插,尾插,判空,获取个数,查找,删除,获取前置和后置位,清空,销毁
  • 在树莓派上使用Nginx搭建本地站点并通过内网穿透实现远程访问
  • 个人网站迁移
  • 由于找不到vcruntime140.dll无法继续执行代码
  • 【Qt6】QStringList
  • 【Midjourney入门教程3】写好prompt常用的参数
  • uniapp在APP端使用swiper进行页面不卡顿滑动
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • Cumulo 的 ClojureScript 模块已经成型
  • Django 博客开发教程 8 - 博客文章详情页
  • docker python 配置
  • Docker入门(二) - Dockerfile
  • Git学习与使用心得(1)—— 初始化
  • go语言学习初探(一)
  • Linux中的硬链接与软链接
  • MySQL QA
  • Python进阶细节
  • quasar-framework cnodejs社区
  • spark本地环境的搭建到运行第一个spark程序
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 复杂数据处理
  • 山寨一个 Promise
  • 一、python与pycharm的安装
  • 用 Swift 编写面向协议的视图
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • # 飞书APP集成平台-数字化落地
  • #QT项目实战(天气预报)
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (TOJ2804)Even? Odd?
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (十一)手动添加用户和文件的特殊权限
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (正则)提取页面里的img标签
  • ***详解账号泄露:全球约1亿用户已泄露
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .NET/C# 使窗口永不获得焦点
  • .NET的数据绑定
  • /etc/fstab 只读无法修改的解决办法