LeetCode322.零钱兑换

文章目录

  • 题目描述
  • 解题思路
    • 递归
    • 记忆化搜索
    • 动态规划
      • 另一种实现

题目描述

https://leetcode.cn/problems/coin-change/description/?envType=study-plan-v2&envId=top-interview-150
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

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

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例 2:

输入:coins = [2], amount = 3
输出:-1
示例 3:

输入:coins = [1], amount = 0
输出:0

提示:

1 <= coins.length <= 12
1 <= coins[i] <= 231 - 1
0 <= amount <= 104

解题思路

  1. 这种找路径,找方法的题一般可以使用回溯法来解决,回溯法也可以说是树形图法,解题的时候使用类似于树状图的结构,使用 自顶而下 的方法。

  2. 而在回溯法中,如果含有很多的重复的计算的时候,就可以使用记忆化的搜索,将可能出现的重复计算大状态使用一个数组来保存其值,在进行重复的计算的时候,就可以直接的调用数组中的值,较少了不必要的递归。

  3. 使用了记忆化搜索后,一般还可以进行优化,在记忆化搜索的基础上,变成 自底而上 的动态规划。

在这里插入图片描述

递归

使用递归就是关键是知道递归函数是用来干什么的,但这里使用递归会超时,因为有太多的重复计算。

class Solution {int res = Integer.MAX_VALUE;public int coinChange(int[] coins, int amount) {if(coins.length == 0){return -1;}findWay(coins,amount,0);// 如果没有任何一种硬币组合能组成总金额,返回 -1。if(res == Integer.MAX_VALUE){return -1;}return res;}public void findWay(int[] coins,int amount,int count){if(amount < 0){return;}if(amount == 0){res = Math.min(res,count);}for(int i = 0;i < coins.length;i++){findWay(coins,amount-coins[i],count+1);}}
}

记忆化搜索

记忆化搜索其实就是在递归的时候,把每个状态保存起来,这样我们递归过程中使用到的重复的结果的时候,不需要在去重新计算,直接从数组中取值,就可以加快速度了。
在这里插入图片描述

从图中可以看出,里面有很多的重复节点,我们使用memo[]来保存节点,memo[n]表示钱币n可以被换取的最少的硬币数,不能换取的话赋值-1。
findway函数的目的是为了找到amount数量的零钱可以兑换的最少硬币数量,返回其值int。
在进行递归的时候,mome[n]被复制了,就不用在继续递归了,可以直接的调用。

class Solution {int[] memo;public int coinChange(int[] coins, int amount) {if(coins.length == 0){return -1;}memo = new int[amount];return findWay(coins, amount);}// memo[n] 表示钱币n可以被换取的最少的硬币数,不能换取就为-1// findWay函数的目的是为了找到 amount数量的零钱可以兑换的最少硬币数量,返回其值intpublic int findWay(int[] coins, int amount){if(amount < 0){return -1;}if(amount == 0){return 0;}// 记忆化的处理,memo[n]用赋予了值,就不用继续下面的循环// 直接的返回memo[n] 的最优值if(memo[amount - 1] != 0){return memo[amount - 1];}int min = Integer.MAX_VALUE;for(int i=0; i < coins.length; i++){int res = findWay(coins, amount - coins[i]);if(res >= 0 && res < min){min = res + 1;// 加1,是为了加上得到res结果的那个步骤中,兑换的一个硬币}}memo[amount - 1] = (min == Integer.MAX_VALUE? -1 : min);return memo[amount - 1];}
}

动态规划

记忆化搜索是在递归的基础上,进行优化。先从memo[amount - 1]开始,从上到下。
动态规划是从memo[0]开始,从下到上。

class Solution {public int coinChange(int[] coins, int amount) {// 自底向上的动态规划if(coins.length == 0){return -1;}// memo[n]的值: 表示的凑成总金额为n所需的最少的硬币个数int[] memo = new int[amount + 1];memo[0] = 0;for(int i=1; i<= amount; i++){int min = Integer.MAX_VALUE;for(int j=0; j<coins.length; j++){if(i - coins[j] >= 0 && memo[i-coins[j]] < min){min = memo[i - coins[j]] + 1;}}memo[i] = min;}return memo[amount] == Integer.MAX_VALUE ? -1 : memo[amount];}
}

另一种实现

memo[i]有两种实现方式,取两者的最小值

  1. 包含当前的coins[i], 那么剩余钱就是i - coins[i], 这种操作要兑换的硬币数是memo[i -coins[j]] + 1
  2. 不包含当前的coins[i],那么要兑换的硬币数就是memo[i]
class Solution {public int coinChange(int[] coins, int amount) {// 自底向上的动态规划if(coins.length == 0){return -1;}// memo[n]的值: 表示的凑成总金额为n所需的最少的硬币个数int[] memo = new int[amount + 1];// 给memo赋初值,最多的硬币数就是全部使用面值1的硬币进行换// amount + 1 是不可能达到的换取数量,于是使用其进行填充Arrays.fill(memo, amount + 1);memo[0] = 0;for(int i=1; i<=amount; i++){for(int j=0; j<coins.length;j++){if(i - coins[j] >= 0){// memo[i]有两种实现的方式,// 一种是包含当前的coins[i],那么剩余钱就是 i-coins[i],这种操作要兑换的硬币数是 memo[i-coins[j]] + 1// 另一种就是不包含,要兑换的硬币数是memo[i]memo[i] = Math.min(memo[i], memo[i-coins[j]] + 1);}}}return memo[amount] == (amount + 1)? -1 : memo[amount];}
}

题解参考:
作者:sugar
链接:https://leetcode.cn/problems/coin-change/solutions/137661/javadi-gui-ji-yi-hua-sou-suo-dong-tai-gui-hua-by-s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/342096.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java商城免 费 搭 建:VR全景到SAAS,各种模式一网打尽!

一、技术选型 java开发语言&#xff1a;java是一种跨平台的编程语言&#xff0c;适用于大型企业级应用开发。使用java开发直播商城可以保证系统的稳定性和可扩展性。 spring boot框架&#xff1a;spring boot是一个快速构建spring应用的框架&#xff0c;简化了开发过程&#xf…

linux动态调试 dev_dbg

动态调试使用方法 打开内核动态调试开关&#xff0c;make menuconfig选中CONFIG_DYNAMIC_DEBUG以及CONFIG_DEBUG_FS Linux启动后&#xff0c;使用命令行挂载上dbgfs 1. mkdir /mnt/dbg 2. mount -t debugfs none /mnt/dbg 1.控制某个文件所有dev_dbg()&#xff0c; echo -n &q…

【React篇 】React项目中常用的工具库

我们可以从项目初始化、开发、构建、检查及发布的顺序总结react项目开发常用的工具库。 首先是初始化。 初始化工程项目一般用官方维护的 create-react-app&#xff0c;这个工具使用起来简单便捷&#xff0c;但 create-react-app 的配置隐藏比较深&#xff0c;修改配置时搭配…

wampserver安装与汉化

wampserver安装与汉化 文章目录 wampserver安装与汉化一、安装二、汉化1.升级软件并安装补丁 介绍&#xff1a; WampServer是一款由法国人开发的Apache Web服务器、PHP解释器以及MySQL数据库的整合软件包。免去了开发人员将时间花费在繁琐的配置环境过程&#xff0c;从而腾出更…

蒙层(css)

如何在 Vue 中实现一个包含图像和蒙层效果的组件&#xff1f;这个组件根据某个条件显示或隐藏蒙层&#xff0c;用于表示图像是否已读。 1. 创建基础模板 首先&#xff0c;我们在模板中使用 div 包裹我们的图像组件 GraphImage&#xff0c;并为最外层 div 设置 position: relat…

【MySQL数据库】MySQL 高可用搭建方案——MHA实战

MHA&#xff08;Master High Availability&#xff09; MHA实战 MHA&#xff08;Master High Availability&#xff09; 一、MHA简介二、MHA搭建准备要求&#xff1a;mha集群搭建&#xff0c;4台服务器&#xff0c;1主2从&#xff0c;1台mha2.1实验思路2.2实验准备 三、搭建MyS…

新手学习编程网站一站式合集

LTPP在线开发平台 探索编程世界的新天地&#xff0c;为学生和开发者精心打造的编程平台&#xff0c;现已盛大开启&#xff01;这个平台汇集了近4000道精心设计的编程题目&#xff0c;覆盖了C、C、JavaScript、TypeScript、Go、Rust、PHP、Java、Ruby、Python3以及C#等众多编程语…

语音深度鉴伪识别项目实战:基于深度学习的语音深度鉴伪识别算法模型(三)音频去噪算法大全+Python源码应用

前言 深度学习技术在当今技术市场上面尚有余力和开发空间的&#xff0c;主流落地领域主要有&#xff1a;视觉&#xff0c;听觉&#xff0c;AIGC这三大板块。 目前视觉板块的框架和主流技术在我上一篇基于Yolov7-LPRNet的动态车牌目标识别算法模型已有较为详细的解说。与AIGC相…

运维开发介绍

目录 1.什么是运维开发 2.作用 3.优点 4.缺点 5.应用场景 5.1.十个应用场景 5.2.网站和Web应用程序 6.案例 7.小结 1.什么是运维开发 运维开发&#xff08;DevOps&#xff09;是一种结合软件开发&#xff08;Development&#xff09;与信息技术运维&#xff08;Opera…

Unity Apple Vision Pro 开发(一):开发前期准备【软硬件要求 | 开发者模式 | 无线调试打包】

文章目录 &#x1f4d5;教程说明&#x1f4d5;硬件要求&#x1f4d5;软件要求⭐Xcode 15.2 及以上⭐visionOS 1.0 (21N301) SDK 或者更高版本⭐Unity 2022 LTS for Apple Silicon (2022.3.18f1及以上的版本)⭐Unity Pro/Unity Enterprise/Unity Industry的授权许可证 &#x1f…

天锐绿盾 | -办公加密系统、数据防泄密软件、图档加密、文件资料防泄密、源代码防止泄露!

天锐绿盾 |- 透明加密、数据防泄密系统、信息安全管理平台&#xff0c;旨在为用户提供全面的数据防泄露解决方案。该系统集成了文件透明加密技术、内网终端安全管理、以及私有云文档管理等功能&#xff0c;能够在不影响用户日常操作习惯和网络开放性的前提下&#xff0c;保护设…

HTML入门

HTML入门 注意&#xff0c;水文自用&#xff0c;//并非HTML注释语言&#xff0c;&#xff08;<&#xff01;–XXX->&#xff09;才是 初始文件结构 Vscode中 &#xff01; tab <!DOCTYPE html> <html lang"en"> //根元素&#xff0c;起始点 &l…

【机器学习基础】Python编程04:五个实用练习题的解析与总结

Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面: 简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。 丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些…

“新高考”下分班怎么分?

来自安徽的张女士告诉我&#xff1a;上一年孩子升入了高中&#xff0c;但没想到才高一&#xff0c;孩子就面临了一个困难的挑选&#xff1a;312”分班&#xff01; 什么是312”分班呢&#xff1f;许多人或许不明白&#xff0c;便是要求学生在高一入学时&#xff0c;针对于3门必…

JVM双亲委派模型

在之前的JVM类加载器篇中说过&#xff0c;各个类加载器都有自己加载的范围&#xff0c;比如引导类加载器只加载Java核心库中的class如String&#xff0c;那如果用户自己建一个包名和类名与String相同的类&#xff0c;会不会被引导类加载器加载。可以通过如下代码测试&#xff0…

HTML静态网页成品作业(HTML+CSS)——企业装饰公司介绍网页(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有4个页面。 二、作品演示 三、代…

探索UWB模块的多功能应用——UWB技术赋能智慧生活

超宽带&#xff08;Ultra-Wideband, UWB&#xff09;技术&#xff0c;凭借其高精度、低功耗和强抗干扰能力&#xff0c;正在成为智能家居领域的一项关键技术。UWB模块的应用不仅提高了智能家居设备的性能&#xff0c;还为家庭安全、设备管理和用户体验带来了显著的改善。 UWB模…

PyTorch 相关知识介绍

一、PyTorch和TensorFlow 1、PyTorch PyTorch是由Facebook开发的开源深度学习框架&#xff0c;它在动态图和易用性方面表现出色。它以Python为基础&#xff0c;并提供了丰富的工具和接口&#xff0c;使得构建和训练神经网络变得简单快捷。 发展历史和背景 PyTorch 是由 Fac…

Python语法详解module3(组合数据类型列表、元组、字典、集合详细用法)

目录 一、列表列表的创建多维列表列表的访问和修改列表的添加和删除列表的遍历使用 for 循环遍历使用 while 循环遍历同时遍历索引和元素列表推导式 常用的列表函数len()sort()reverse()index()count()extend()clear() 二、元组创建元组访问元组元素元组的不可变性元组的优点元…

Python3 迭代器和生成器

前言 本文主要介绍Python中的迭代器和生成器&#xff0c;主要内容包括 迭代器概述、生成器简介。 文章目录 前言一、迭代器简介二、生成器简介 一、迭代器简介 在 Python 中&#xff0c;迭代器(iterator)是一个实现了迭代器协议&#xff08;Iterator Protocol&#xff09;的…