代码随想录算法训练营第四十五天 | 力扣 70. 爬楼梯(进阶), 322. 零钱兑换, 279.完全平方数

news/2024/11/29 6:29:28/

70. 爬楼梯(进阶)

题目

70. 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

改为:一步一个台阶,两个台阶,三个台阶,.......,直到 m个台阶。问有多少种不同的方法可以爬到楼顶呢

解析

1阶,2阶,.... m阶就是物品,楼顶就是背包。

每一阶可以重复使用,例如跳了1阶,还可以继续跳1阶。

问跳到楼顶有几种方法其实就是问装满背包有几种方法。

此时大家应该发现这就是一个完全背包问题了!

1.确定dp数组以及下标的含义

dp[i]:爬到有i个台阶的楼顶,有dp[i]种方法

2.确定递推公式

求装满背包有几种方法,递推公式一般都是dp[i] += dp[i - nums[j]];

本题呢,dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]

那么递推公式为:dp[i] += dp[i - j]

3.dp数组如何初始化

既然递归公式是 dp[i] += dp[i - j],那么dp[0] 一定为1,dp[0]是递归中一切数值的基础所在,如果dp[0]是0的话,其他数值都是0了。

4.确定遍历顺序

这是背包里求排列问题,即:1、2 步 和 2、1 步都是上三个台阶,但是这两种方法不一样!

所以需将target放在外循环,将nums放在内循环。

每一步可以走多次,这是完全背包,内循环需要从前向后遍历。

5.举例来推导dp数组

Java代码实现

public int climbNStairs(int n,int m){int[] dp = new int[n + 1];dp[0] = 1;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (i - j > 0) {dp[i] += dp[i - j];}}}return dp[n];
}

322. 零钱兑换

题目

322. 零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

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

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

解析

1.确定dp数组以及下标的含义

dp[j]:凑足总额为j所需钱币的最少个数为dp[j]

2.确定递推公式

凑足总额为j - coins[i]的最少个数为dp[j - coins[i]],那么只需要加上一个钱币coins[i]即dp[j - coins[i]] + 1就是dp[j](考虑coins[i])

所以dp[j] 要取所有 dp[j - coins[i]] + 1 中最小的。

递推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);

3.dp数组如何初始化

首先凑足总金额为0所需钱币的个数一定是0,那么dp[0] = 0;

考虑到递推公式的特性,dp[j]必须初始化为一个最大的数,否则就会在min(dp[j - coins[i]] + 1, dp[j])比较的过程中被初始值覆盖。

所以下标非0的元素都是应该是最大值。

4.确定遍历顺序

本题求钱币最小个数,那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数

本题并不强调集合是组合还是排列。

采用coins放在外循环,target在内循环的方式。

遍历顺序为:coins(物品)放在外循环,target(背包)在内循环。且内循环正序。

5.举例推导dp数组

以输入:coins = [1, 2, 5], amount = 5为例

Java代码实现

public int coinChange(int[] coins, int amount) {int max = Integer.MAX_VALUE;int[] dp = new int[amount + 1];Arrays.fill(dp, max);dp[0] = 0;for (int i = 0; i < coins.length; i++) {for (int j = coins[i]; j <= amount; j++) {if (dp[j - coins[i]] != max) {dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);}}}return dp[amount] == max ? -1 : dp[amount];
}

279.完全平方数 

题目

279. 完全平方数

给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。

解析

1.确定dp数组(dp table)以及下标的含义

dp[j]:和为j的完全平方数的最少数量为dp[j]

2.确定递推公式

dp[j] 可以由dp[j - i * i]推出, dp[j - i * i] + 1 便可以凑成dp[j]。

此时我们要选择最小的dp[j],所以递推公式:dp[j] = min(dp[j - i * i] + 1, dp[j]);

3.dp数组如何初始化

dp[0]表示 和为0的完全平方数的最小数量,那么dp[0]一定是0。

从递归公式dp[j] = min(dp[j - i * i] + 1, dp[j]);中可以看出每次dp[j]都要选最小的,所以非0下标的dp[j]一定要初始为最大值,这样dp[j]在递推的时候才不会被初始值覆盖

4.确定遍历顺序

我们知道这是完全背包,

本题是求最小数!

所以本题外层for遍历背包,内层for遍历物品,还是外层for遍历物品,内层for遍历背包,都是可以的!

5.举例推导dp数组

已输入n为5例,dp状态图如下:

Java代码实现

public int numSquares(int n) {int max = Integer.MAX_VALUE;int[] dp = new int[n + 1];for (int i = 0; i < dp.length; i++) {dp[i] = max;}dp[0] = 0;for (int i = 1; i * i <= n; i++) {for (int j = i * i; j <= n; j++) {if (dp[j - i * i] != max) {dp[j] = Math.min(dp[j], dp[j - i * i] + 1);}}}return dp[n] == max ? -1 : dp[n];
}

http://www.ppmy.cn/news/104940.html

相关文章

SocketTools .NET Edition 11.0 Crack

SocketTools .NET Edition 一套 .NET 类&#xff0c;可轻松向软件添加 Internet 功能&#xff0c;支持 .NET 4.0 至 .NET 8.0。 特征 SocketTools 提供入门所需的一切&#xff0c;包括文档和示例&#xff0c;以及免费技术支持来回答您的开发问题。 Visual Studio 2022 和 .NE…

《简单的http网站的构建》

【一】什么是协议 通过udp和tcp协议大家知道&#xff0c;无论是以数据报还是字节流的方式去把信息传送出去&#xff0c;都需要将我们所有的信息转化为字符串的形式进行发送&#xff0c;这叫序列化&#xff0c;在另外一头将字符串转化为我们所需要的信息&#xff0c;这是反序列…

Python中如何打印输出?

当你开始学习Python编程语言时&#xff0c;第一个要学习的内容之一就是如何在Python中打印输出。这个问题可能看起来很简单&#xff0c;但它实际上包含了许多不同的方面。在本篇博客中&#xff0c;我将向您展示如何在Python中进行基本的输出&#xff0c;并介绍一些高级用法和技…

vue3-组件之间的通信

1、父 传 子&#xff1a;props 父&#xff1a; 传入 msg 和 school信息 <Demo msg"圣墟" school"陈东" />子&#xff1a;接收 信息&#xff0c;可直接{{msg}} 使用 const props defineProps([msg,school])2、子传父&#xff08;自定义事件&#…

【C++】结构体 - 定义和使用,结构体数组,结构体指针,结构体嵌套结构体,结构体做函数参数,结构体const

文章目录 1. 定义和使用2. 结构体数组3. 结构体指针4. 结构体嵌套结构体5. 结构体做函数参数6. 结构体const 1. 定义和使用 结构体属于用户自定义的数据类型&#xff0c;允许用户存储不同的数据类型。 struct 结构体 {结构体成员列表}; 通过结构体创建变量的方法有三种&…

MATLAB机器学习:分类、回归和聚类的算法实现和模型优化

第一章&#xff1a;引言 机器学习是当今IT领域最热门的话题之一&#xff0c;它为我们提供了解决复杂问题的新方法。MATLAB作为一种功能强大的编程语言和环境&#xff0c;提供了许多用于机器学习的工具和函数。本文将介绍MATLAB中常用的分类、回归和聚类算法的实现&#xff0c;…

RK3588平台开发系列讲解(基础篇)Linux 内核有多少 API 接口

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、Linux 内核有多少 API 接口二、Linux 系统调用表三、Linux 系统调用实现3.1、申明系统调用3.2、定义系统调用沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 Linux 作为比较成熟的操作系统,功能完善,它…

安装VMware Workstation和虚拟机教程

一、VM简介   VMware Workstation中文版是一个“虚拟 PC”软件。它使你可以在一台机器上同时运行二个或更多 Windows、DOS、LINUX 系统。与“多启动”系统相比&#xff0c;VMWare 采用了完全不同的概念。多启动系统在一个时刻只能运行一个系统&#xff0c;在系统切换时需要重…