代码随想录算法训练营Day45 | 70. 爬楼梯 (进阶) | 322. 零钱兑换 | 279. 完全平方数
文章目录
- 70. 爬楼梯 (进阶)
- 322. 零钱兑换
- 二维数组
- 滚动数组
- 279. 完全平方数
70. 爬楼梯 (进阶)
题目链接 | 理论基础
以完全背包的思路来解题,正如组合总和 Ⅳ 中提到的一样。在本题中,先背包后物品的思路就显得非常合理明显了。
本题中的物品就是可以行走的步数 [1, 2],重量是 n,可以重复选取步数,求走到第 n 层有多少种走法。这样抽象过后,就和组合总和 Ⅳ 一样是求排列了。
- dp 的下标含义:
dp[j]
是到达第 j 层的方法数 - dp 递推公式:
dp[j] += dp[j - i]
- dp 数组的初始化:根据递推公式可以得知
dp[0]=1
是必须的,也符合前两层的结果,其他的初始化为 0。 - dp 遍历顺序:需要得到排列结果,先背包后物品(在爬楼梯的背景下就很合理)
- 举例推导:省略
class Solution:def climbStairs(self, n: int) -> int:choices = [1, 2]# dp[i] represents the number of ways to reach position idp = [0] * (n+1)dp[0] = 1# dp formulafor j in range(n+1):for i in range(len(choices)):if j >= choices[i]:dp[j] += dp[j-choices[i]]return dp[-1]
本题看上去是个简单的爬楼梯,但实际上是个简单的完全背包,重要的是可以考验对物品和背包的遍历顺序的理解。事实上,以后遇到排列的完全背包问题,以爬楼梯的思路来理解会非常有效!
322. 零钱兑换
题目链接 | 理论基础
本题和 零钱兑换II 非常相似,依然是典型的完全背包问题。区别在于,零钱兑换II 需要组合数,这就规定了滚动数组的遍历顺序;本题只需要最小组合数,而不在乎得到该最小数的方式是组合或是排列。
二维数组
-
dp 数组的下标含义:
dp[i][j]
,使用硬币 [0, i] 组成金额j
所使用的最小硬币数 -
dp 递推公式:
dp[i][j] = min(dp[i-1][j], dp[i-1][j-coins[i]] + 1)
-
dp 的初始化:本题的大坑!
- 二维数组的初始化中 ,
coins[0]
(i=0)和 j=0 的情况是比较容易想到的:- 只能使用一个硬币时,只有该硬币面值的整数倍金额 j 会初始化为
j // coins[0]
- 当金额为 0 的时候,不管有多少硬币可以使用,都只需要 0 个硬币即可达成金额 0
- 只能使用一个硬币时,只有该硬币面值的整数倍金额 j 会初始化为
- 那些不需要特殊初始化的位置才是需要小心的!
- 由于题目要求“无法构成金额的情况返回 -1”,自然想到应该优先把所有值初始化为 -1。这么做就会有下面第一种复杂的解法,要考虑
min()
中每个元素为 -1 的情况,堪称崩溃。 - 由于
min()
的特性,最好的初始化应该是float('inf')
,这样不会影响后续的递推,也不会影响初始化,只需要在最后检查结果是否是float('inf')
即可。 - 如果被题目默认的初始化条件所迷惑,而没有认识到
min()
的需求,那就会踩坑(虽然也能解决问题)。
- 由于题目要求“无法构成金额的情况返回 -1”,自然想到应该优先把所有值初始化为 -1。这么做就会有下面第一种复杂的解法,要考虑
- 二维数组的初始化中 ,
-
dp 的遍历顺序:由于不需要排列,二维数组可以解决,物品和背包的顺序无所谓。
-
举例推导:
coins = [1, 2, 5], amount = 5
0 1 2 3 4 5 1 0 1 2 3 4 5 2 0 1 1 2 2 3 5 0 1 1 2 2 1
class Solution:def coinChange(self, coins: List[int], amount: int) -> int:# dp[i][j] represents the smallest number to make j using coins [0, i]dp = [[-1] * (amount + 1) for _ in range(len(coins))]for j in range(amount + 1):if j % coins[0] == 0:dp[0][j] = j // coins[0]for i in range(len(coins)):dp[i][0] = 0# dp formulafor i in range(1, len(coins)):for j in range(amount + 1):if j < coins[i]:dp[i][j] = dp[i-1][j]else:if dp[i-1][j] >= 0 and dp[i][j-coins[i]] >= 0:dp[i][j] = min(dp[i-1][j], dp[i][j-coins[i]] + 1)elif dp[i-1][j] == -1 and dp[i][j-coins[i]] >= 0:dp[i][j] = dp[i][j-coins[i]] + 1elif dp[i-1][j] >= 0 and dp[i][j-coins[i]] == -1:dp[i][j] = dp[i-1][j]else:dp[i][j] = -1return dp[-1][-1]
正确初始化的解法
class Solution:def coinChange(self, coins: List[int], amount: int) -> int:# dp[i][j] represents the smallest number to make j using coins [0, i]dp = [[float('inf')] * (amount + 1) for _ in range(len(coins))]for j in range(amount + 1):if j % coins[0] == 0:dp[0][j] = j // coins[0]for i in range(len(coins)):dp[i][0] = 0# dp formulafor i in range(1, len(coins)):for j in range(amount + 1):if j < coins[i]:dp[i][j] = dp[i-1][j]else:dp[i][j] = min(dp[i-1][j], dp[i][j-coins[i]] + 1)return dp[-1][-1] if dp[-1][-1] != float('inf') else -1
滚动数组
之前做过的几道完全背包,先物品后背包是求组合种类问题,先背包后物品是求排列种类问题。如上所述,本题只要求满足金额的硬币数,不在意满足金额的结果的顺序,所以物品、背包的遍历顺序都可以。
class Solution:def coinChange(self, coins: List[int], amount: int) -> int:# dp[i][j] represents the smallest number to make j using coins [0, i]dp = [-1] * (amount + 1)dp[0] = 0# dp formulafor i in range(len(coins)):for j in range(amount + 1):if j >= coins[i]:if dp[j] >= 0 and dp[j-coins[i]] >= 0:dp[j] = min(dp[j], dp[j-coins[i]] + 1)elif dp[j] == -1 and dp[j-coins[i]] >= 0:dp[j] = dp[j-coins[i]] + 1elif dp[j] >= 0 and dp[j-coins[i]] == -1:dp[j] = dp[j]else:dp[j] = -1return dp[-1]
正确初始化的解法
class Solution:def coinChange(self, coins: List[int], amount: int) -> int:# dp[i][j] represents the smallest number to make j using coins [0, i]dp = [float('inf')] * (amount + 1)dp[0] = 0# dp formulafor i in range(len(coins)):for j in range(amount + 1):if j >= coins[i]:dp[j] = min(dp[j], dp[j-coins[i]] + 1)return dp[-1] if dp[-1] != float('inf') else -1
279. 完全平方数
题目链接 | 理论基础
本题乍一看和完全背包没什么关系。将完全平方数 1,4,9 … 看作是物品,n 看作是背包容量的话,就又是一道标准的完全背包问题:求填满背包使用的最少物品数。抽象过后,本题和上一题几乎是一模一样。
唯一的区别在于,由于 n 的范围很大,在 n 取较大值的时候会耗时较长。二维数组会直接超时,而滚动数组也需要直接利用更新范围来减少遍历时间。这也是第一道二维数组无法解题的背包问题。
class Solution:def numSquares(self, n: int) -> int:# dp[j] represents the number of ways to make jdp = [float('inf')] * (n+1)dp[0] = 0max_sqrt_num = int(sqrt(n))# dp formulafor i in range(max_sqrt_num):for j in range((i+1) * (i+1), n+1):dp[j] = min(dp[j], dp[j-(i+1)*(i+1)] + 1)return dp[-1]
相关文章:
代码随想录算法训练营Day45 | 70. 爬楼梯 (进阶) | 322. 零钱兑换 | 279. 完全平方数
文章目录 70. 爬楼梯 (进阶)322. 零钱兑换二维数组滚动数组 279. 完全平方数 70. 爬楼梯 (进阶) 题目链接 | 理论基础 以完全背包的思路来解题,正如组合总和 Ⅳ 中提到的一样。在本题中,先背包后物品的思路就显得非常合理明显了。 本题中的物品就是可…...
算法训练营第四十一天(9.2)| 动态规划Part11:最长公共子序列
Leecode 1143.最长公共子序列 题目地址:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题目类型:最长子序列 class Solution { public:int longestCommonSubsequence(string text1, string text2) {int m text1.size(), n t…...
k8s基于rbac权限管理serviceAccount授权管理
测试通过http访问apiServer curl没有证书不能通过https来访问apiServer需要使用kubectl代理 #使用kubectl代理 kubectl proxy --port8111& #curl访问 api/v1 是资源所属群组/版本 即创建资源时定义的apiVersion #后边跟的是要访问的资源 #查看所有命名空间 #查看核心资源用…...
linux URL访问工具
URL访问工具 有时候想在命令行下通过http访问接口/网页,可以使用curl来进行操作 发起请求 curl www.baidu.com 会返回网页内容 参数选项 -i参数 使用-i参数,会返回响应header curl -i www.baidu.com -I参数 使用-I参数,只会返回响应header cu…...
CCF-CSP 29次 第五题【202303-5 施肥】
计算机软件能力认证考试系统 题解(35分): 枚举每个区间,再枚举每个施肥车,看所有的施肥车能不能把这个区间填满 #include<bits/stdc.h> using namespace std; const int N410; int n,m; typedef pair<int,…...

前端基础4——jQuery
文章目录 一、基本了解1.1 导入jQuery库1.2 基本语法1.3 选择器 二、操作HTML2.1 隐藏和显示元素2.2 获取与设置内容2.3 获取、设置和删除属性2.4 添加元素2.5 删除元素2.6 设置CSS样式 三、jQuery Ajax3.1 基本语法3.2 回调函数3.3 常用HTTP方法3.4 案例一3.4.1 准备工作3.4.2…...

测试人:“躺平?不可能的“, 盘点测试人在职场的优势
之前有这么一个段子:有人喜欢创造世界,他们做了程序员;有人喜欢拯救世界,他们做了测试员!近几年,测试工程师在企业究竟是怎么样的发展?随着企业对于用户体验的满意度越来越重视,更加…...

C++:初识类与this指针
文章目录 前言一、类类的定义和实例化类的访问限定符类的作用域计算类的大小 二、类的成员函数的this指针总结 个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》 前言 一、类 类的定义和实例化 注意类定义结束时后面分号( ; )不能省略。 类…...

2023应届生java面试紧张失误之一:CAS口误说成开心锁-笑坏面试官
源于:XX网,如果冒犯,表示歉意 面试官:什么是CAS 我:这个简单,开心锁 面试官:WTF? 我:一脸自信,对,就是这个 面试官:哈哈大笑ÿ…...

Excel_VBA程序文件的加密及解密说明
VBA应用技巧及疑难解答 Excel_VBA程序文件的加密及解密 在您看到这个文档的时候,请和我一起念:“唵嘛呢叭咪吽”“唵嘛呢叭咪吽”“唵嘛呢叭咪吽”,为自己所得而感恩,为付出者赞叹功德。 本不想分享之一技术,但众多学…...
Flutter关于StatefulWidget中State刷新时机的一点实用理解
刚入门flutter开发,使用StatefulWidget踩了很多坑,就我遇到典型问题谈谈见解。 1.initState方法只会在控件初始化的时候执行一遍。 2.控件内部执行setState方法,则会每次执行build方法。 3.控件销毁会执行dispose方法,所以一些…...

CS420 课程笔记 P2 - 内存编辑和基础的 GameHacking 尝试
文章目录 IntroductionOperating SystemToolsMemory ScanningMemory ScanExamples!Conclusion Introduction 本节将介绍操作系统的基础知识和内存扫描,这可以说是 game hacking 中最重要的技能,我们不会深入讨论操作系统,因为这本身就是一门…...
【sql】MongoDB 查询 高级用法
【sql】MongoDB 查询 高级用法 一、基本查询指定字段 db.getCollection(students).find({}, {name: 1, score: 1}) 二、指定字段别名 db.getCollection(students).find({}, {"name":1, "score":1, "grade":"$grade.grade"}) 这里将…...
监督学习的介绍
一、定义 监督学习是利用一组已知类别的样本调整分类器的参数,使其达到所要求性能的过程,也称为监督训练或有教师学习。它是一种机器学习的方法,目的是让模型能够从已知的输入和输出之间的关系中学习,并且能够对新的输入做出正确…...

【DRONECAN】(三)WSL2 及 ubuntu20.04 CAN 驱动安装
【DRONECAN】(三)WSL2 及 ubuntu20.04 CAN 驱动安装 前言 这一篇文章主要介绍一下 WSL2 及 ubuntu20.04 CAN 驱动的安装,首先说一下介绍本文的目的。 大家肯定都接触过 ubuntu 系统,但是我们常用的操作系统都是 Windows&#x…...

Databricks 入门之sql(二)常用函数
1.类型转换函数 使用CAST函数转换数据类型(可以起别名) SELECTrating,CAST(timeRecorded as timestamp) FROMmovieRatings; 支持的数据类型有: BIGINT、BINARY、BOOLEAN、DATE 、DECIMAL(p,s)、 DOUBLE、 FLOAT、 INT、 INTERVAL interva…...

Simulink建模与仿真(3)-Simulink 简介
分享一个系列,关于Simulink建模与仿真,尽量整理成体系 1、Simulink特点 Simulink是一个用来对动态系统进行建模、仿真和分析的软件包。使用Simulink来建模、分析和仿真各种动态系统(包括连续系统、离散系统和混合系统),将是一件非常轻松的事…...

(超简单)将图片转换为ASCII字符图像
将一张图片转换为ASCII字符图像 原图: 效果图: import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileWriter; import java.io.IOException;public class ImageToASCII {/*** 将图片转换为A…...
In-Context Retrieval-Augmented Language Models
本文是LLM系列文章,针对《In-Context Retrieval-Augmented Language Models》的翻译。 上下文检索增强语言模型 摘要1 引言2 相关工作3 我们的框架4 实验细节5 具有现成检索器的上下文RALM的有效性6 用面向LM的重新排序改进上下文RALM7 用于开放域问答的上下文RALM…...
多种免费天气api
多种免费天气api推荐 一、高德天气二、格点天气三、香港天文台 一、高德天气 api说明文档:https://lbs.amap.com/api/webservice/guide/api/weatherinfo 实例代码: import requests# 香港天文台API的URL api_url "https://restapi.amap.com/v3/w…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...