LeetCode 热题100之 动态规划1

对于动态规划的问题,解题步骤有以下几部(总结为动态规划五部曲:参考代码随想录动态规划

  1. 确定dp数组以及下标的含义;
  2. 确定递推公式;
  3. dp数组如何初始化;
  4. 确定遍历顺序;
  5. 举例推导dp数组

下面的解题思路分析都将从以上动规五部曲展开。

1.爬楼梯

在这里插入图片描述
思路分析:动规五部曲

  • dp[i]:达到i阶楼梯有i种方法;
  • 递推公式;由于当前状态可以由前一种状态走一步到达也可以由前两的状态走两步到达,所以dp[i] = dp[i - 1] + dp[i - 2];
  • 初始化:题目中n是正整数,所以初始化:dp[1] = 1,dp[2] = 2即可;
  • 遍历顺序:因为要保证计算的时候所用的dp[i-1]和dp[i-2]是更新后的,所以要从前往后遍历;
  • 打印dp数组(debug):1,2,3,5,8…

具体实现代码(详解版):

class Solution {
public:int climbStairs(int n) {vector<int> dp(n + 1,0);if(n == 1) return 1;if(n == 2) return 2;dp[1] = 1,dp[2] = 2;//初始化for(int i = 3; i <= n ; i ++){dp[i] = dp[i - 1] + dp[i - 2];//递推公式}return dp[n];}
};

当然,实际上,我们只关心 dp[i-1] 和 dp[i-2],因此可以将数组的空间复杂度从 O(n) 降到 O(1),使用两个变量来存储最近的两个结果。

class Solution {
public:int climbStairs(int n) {int p = 0 ,q = 0 ,r = 1;for(int i = 1 ; i <= n ; i ++){p = q;q = r;r = p + q;}return r;}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

2.杨辉三角

在这里插入图片描述
思路分析:动规五部曲

  • dp数组:dp[i][j]表示杨辉三角第i+1行第j+1列的元素。其中i从0-numRows,j从0~i
  • 递推公式:每行的第一个和最后一个元素是 1,其他元素是上一行相邻两个元素之和。所以递推公式为dp[i][j] = dp[i - 1][j] +dp[i - 1][j - 1];
  • 初始化当前行:dp[i][0] = 1,dp[i][i] = 1;
  • 遍历顺序:由于是从上往下依次填充元素,所以应该从第0行从前往后遍历;
  • 举例推导dp数组

[
[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1]
]

具体实现代码(详解版):

class Solution {
public:vector<vector<int>> generate(int numRows) {vector<vector<int>> dp(numRows);for(int i = 0 ; i < numRows ; i ++){//初始化当前行dp[i].resize(i + 1);dp[i][0] = dp[i][i] = 1;//计算中间元素:上一行相邻元素之和for(int j = 1 ; j < i ; j ++){dp[i][j] = dp[i - 1][j] +dp[i - 1][j - 1];//递推公式}}return dp;}
};
  • 时间复杂度: O ( n u m R o w s 2 ) O(numRows^2) O(numRows2)
  • 空间复杂度: O ( n u m R o w s 2 ) O(numRows^2) O(numRows2),存储杨辉三角的所有元素

3.打家劫舍

在这里插入图片描述
思路分析:动归五部曲

  • dp[i]:表示抢劫到第i家的最大金额;
  • 递推公式:这道题目可以分为两种情况
    • 不抢第i家,则此时最大金额为dp[i - 1];
    • 抢第i家,则此时最带金额为dp[i - 2] + nums[i],即加上 i 家的金额和不抢相邻的 i-1 家的最大金额;
    • 最终递推公式:d[i] = max(dp[i - 1],dp[i - 2] + nums[i]);
  • 初始化:dp[0]=nums[0],这是直接抢劫第一家;dp[1] = max(nums[0],nums[1]),是取第一家和第二家中较大的金额,因为你不能同时抢劫第一家和第二家。
  • 遍历顺序:从前往后,因为后面的金额与前面的金额有关系,且确保是计算过的值参与后续的更新;
  • 打印DP数组:可以debug

具体实现代码(详解版):

class Solution {
public:int rob(vector<int>& nums) {int n = nums.size();  // 获取nums数组的大小vector<int> dp(n);     // 创建一个dp数组,长度为n,用来保存到每个位置的最大抢劫金额// 边界条件:if (n == 0) return 0;  // 如果数组为空,返回0if (n == 1) return nums[0];  // 如果只有一个房子,直接返回它的金额// 初始化前两个位置的dp值dp[0] = nums[0];  // 第一个房子的最大抢劫金额就是nums[0]dp[1] = max(nums[0], nums[1]);  // 第二个房子的最大抢劫金额是nums[0]和nums[1]中的较大值// 动态规划状态转移:从第3个房子开始计算for (int i = 2; i < n; i++) {dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);  // 选择是否抢劫第i个房子}// 返回最大抢劫金额,即最后一个房子对应的dp值return dp[n - 1];}
};

其实我们只需要记录 dp[i-1] 和 dp[i-2],而不需要完整的 dp 数组。我们可以将 dp[i-1] 和 dp[i-2] 分别存储在两个变量中,从而不再需要 dp 数组:
具体实现代码(详解版):

class Solution {
public:int rob(vector<int>& nums) {int n = nums.size();if (n == 0) return 0;  if (n == 1) return nums[0]; // 初始化:first代表dp[i-2],second代表dp[i-1]int first = nums[0];  // dp[0],即第一个房子可以抢到的金额int second = max(nums[0], nums[1]);  // dp[1],即第二个房子可以抢到的最大金额// 从第3个房子开始,更新状态for (int i = 2; i < n; i++) {int current = max(second, first + nums[i]);  // 当前房子的最大抢劫金额first = second;  // 更新dp[i-2]second = current;  // 更新dp[i-1]}return second;  // 最终返回second,即最大抢劫金额}
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

4.完全平方数

在这里插入图片描述
思路分析:动规五部曲

  • dp[i]:表示和为i的最少完全平方数的个数
  • 递推公式
    • 完全平方数的特点是:如果一个数可以被表示为若干个完全平方数之和,那么它的最小完全平方数的个数应该是通过某种方式组合这些完全平方数的最小数量。
    • 假设我们已经知道 dp[i - j^2],其中 j 是一个整数,表示一个完全平方数。那么 dp[i] 就可以通过 dp[i - j^2] + 1 来更新,表示通过加上一个完全平方数 j^2 来达到总和 i。
    • 那么递推公式就是:dp[i] = min(dp[i], dp[i - j^2] + 1),其中,j^2 是小于等于 i 的所有完全平方数。
  • 初始化:dp[0] = 0;表示和为0的最小数量为0
  • 遍历顺序
    • 外层循环遍历所有 i 从 1 到 n。
    • 内层循环遍历所有可能的完全平方数 j^2(即 j 从 1 开始,直到 j^2 大于 i)。
  • 打印dp数组:debug

具体实现代码(详解版):

class Solution {
public:int numSquares(int n) {vector<int> dp(n + 1, INT_MAX);dp[0] = 0; // 0 需要 0 个完全平方数for (int i = 1; i <= n; i++) {for (int j = 1; j * j <= i; j++) {dp[i] = min(dp[i], dp[i - j * j] + 1);//递推公式}}return dp[n];}
};
  • 时间复杂度:O(n * sqrt(n)),其中 n 是输入的整数。每个 i 的计算需要遍历所有小于等于 i 的完全平方数,最多进行 sqrt(n) 次操作。
  • 空间复杂度:O(n),我们使用了一个长度为 n+1 的数组来保存状态。

5.零钱兑换

在这里插入图片描述

  • dp[i]:组成金额为i所需的最少硬币数;
  • 递推公式
    • 对于每一个金额 i(从 1 到 amount),你会检查每种硬币面额 coins[j].如果硬币面额 coins[j] 小于或等于当前金额 i,则可以通过 dp[i - coins[j]] 来获得剩余金额的最小硬币数,再加上当前硬币得到新的结果。
    • dp[i] = min(dp[i], dp[i - coins[j] + 1),其中 coins[j] 为当前考虑的硬币面额。
  • 初始化:
    • dp(amount + 1,amount + 1);这里初始化为amount + 1很重要,amount + 1是因为最多也就是amount个1相加,再多就不可能了 使用INT_MAX也可以做到,但是一旦遇到 dp[i - coin] + 1 就会导致int范围溢出,需要额外判断,或者使用其他类型比如long long,或者也可以取数据范围外的特殊值,但都取特殊值的了话还不如用这个amount + 1
    • dp[0]=0;表示组成金额为0不需要任何硬币;
  • 遍历顺序
    • 外层循环遍历所有金额 i 从 1 到 amount;
    • 内存循环遍历每个硬币,对每个金额i,我们都要检查每种硬币是否能参与组成该金额(即coins[j] <= i),进而更新dp[i].
  • 打印dp数组:debug

具体实现代码(详解版):

class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount + 1,amount + 1);dp[0] = 0;for(int i = 1 ; i <= amount ; i ++){for(int j = 0 ; j < coins.size() ; j ++){if(coins[j] <= i){//硬币面额不超过当前金额dp[i] = min(dp[i],dp[i - coins[j]] + 1);}}}//因为初始化为amount + 1,若没更新就是没找到组合方式,判断即可。return  dp[amount] > amount ? -1 : dp[amount];}
};
  • 时间复杂度:O(amount *m),其中其中 amount 是目标金额,m 是硬币的种类数。外层循环遍历金额 1 到 amount,内层循环遍历所有硬币,导致总的时间复杂度为 O(amount * m)。
  • 空间复杂度:O(amount),我们使用一个长度为 amount + 1 的 dp 数组来保存每个金额所需的最少硬币数。

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

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

相关文章

python可视化将多张图整合到一起(画布)

这周有点事忙着&#xff0c;没时间重温刚结束的Mathurcup数学建模&#xff0c;这两天也是再看了下&#xff0c;论文还是赶紧挺烂的&#xff0c;但比国赛又有进步&#xff08;说起国赛又不得不抱怨了&#xff0c;基本其余省份都发了&#xff0c;但江西......哎&#xff09;。哎&…

MFC图形函数学习07——画扇形函数

绘制扇形函数是MFC中绘图的基本函数&#xff0c;它绘制的仍是由椭圆弧与椭圆中心连线构成的椭圆扇形&#xff0c;特例是由圆弧与圆心连线构成的圆扇形。 一、绘制扇形函数 原型&#xff1a;BOOL Pie(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4); …

vue 依赖注入(Provide、Inject )和混入(mixins)

Prop 逐级透传问题​ 通常情况下&#xff0c;当我们需要从父组件向子组件传递数据时&#xff0c;会使用 props。想象一下这样的结构&#xff1a;有一些多层级嵌套的组件&#xff0c;形成了一棵巨大的组件树&#xff0c;而某个深层的子组件需要一个较远的祖先组件中的部分数据。…

手机上用什么方法可以切换ip

手机上用什么方法可以切换IP&#xff1f;在某些特定情境下&#xff0c;用户可能需要切换手机的IP地址&#xff0c;以满足网络安全、隐私保护或绕过地域限制等需求。下面以华为手机为例&#xff0c;将详细介绍手机IP地址切换的几种方法&#xff0c;帮助用户轻松实现这一目标。 一…

一个强大的Stable Diffusion comfyUI 工作流,能实现写真自由、各种风格融合、面部特征一致性等等

今天&#xff0c;我们将向您介绍一款非常实用的工具——Stable Diffusion comfyUI工作流。这款工作流基于Stable Diffusion技术&#xff0c;旨在为您提供一键式生成图像的便捷体验。无论您是AI绘画的新手还是专业人士&#xff0c;这个工作流都能为您带来极大的便利。 在这个教…

外泌体相关基因肝癌临床模型预测——2-3分纯生信文章复现——6.外泌体基因功能注释(二)

内容如下: 1.外泌体和肝癌TCGA数据下载 2.数据格式整理 3.差异表达基因筛选 4.预后相关外泌体基因确定 5.拷贝数变异及突变图谱 6.外泌体基因功能注释 7.LASSO回归筛选外泌体预后模型 8.预后模型验证 9.预后模型鲁棒性分析 10.独立预后因素分析及与临床的相关性分析…

【Homework】【1--4】Learning resources for DQ Robotics in MATLAB

Learning resources for DQ Robotics in MATLAB Lesson 1 代码 % Step 2: Define the real numbers a1 and a2 a1 123; a2 321;% Step 3: Calculate and display a3 a1 a2 a3 a1 a2; disp([a3 (a1 a2) , num2str(a3)])% Step 4: Calculate and display a3 a1 * a2 a3…

linux命令详解,存储管理相关

存储管理 一、内存使用量&#xff0c;free free 命令是一个用于显示系统中物理内存&#xff08;RAM&#xff09;和交换空间&#xff08;swap&#xff09;使用情况的工具 free -m free -m -s 5参数 -b 功能: 以字节&#xff08;bytes&#xff09;为单位显示内存使用情况。说…

推荐一款功能强大的视频修复软件:Apeaksoft Video Fixer

Apeaksoft Video Fixer是一款功能强大的视频修复软件&#xff0c;专门用于修复损坏、不可播放、卡顿、画面失真、黑屏等视频问题。只需提供一个准确且有效的样本视频作为参考&#xff0c;该软件就能将受损视频修复到与样本视频相同的质量。该软件目前支持MP4、MOV、3GP等格式的…

Redis如何保证数据不丢失(可靠性)

本文主要以学习为主&#xff0c;详细参考&#xff1a;微信公众平台 Redis 保证数据不丢失的主要手段有两个&#xff1a; 持久化 多机部署 我们分别来看它们两的具体实现细节。 1.Redis 持久化 持久化是指将数据从内存中存储到持久化存储介质中&#xff08;如硬盘&#xf…

第三十九章 基于VueCli自定义创建项目

目录 1. 选择创建模式 2. 选择需要的功能 3. 选择历史模式还是哈希模式 ​4.CSS预处理器 5. 选择ESLint规则 6. 开始创建项目 ​7. 自定义项目最终结构 1. 选择创建模式 输入创建的项目名&#xff0c;创建项目&#xff1a; 这里选择自定义模式&#xff1a; 2. 选择需要…

【Vue3】基础语法案例

图片点击轮播 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>图片轮播</title> </head><body><div id"app"><h3>{{ number }}</h3><!-- 通过模板字…

【大数据学习 | kafka高级部分】kafka的kraft集群

首先我们分析一下zookeeper在kafka中的作用 zookeeper可以实现controller的选举&#xff0c;并且记录topic和partition的元数据信息&#xff0c;帮助多个broker同步数据信息。 在新版本中的kraft模式中可以这个管理和选举可以用kafka自己完成&#xff0c;而不再依赖zookeeper。…

生物发酵装备在制药工业中的应用与发展前景

在现代制药工业中&#xff0c;发酵技术扮演着越来越重要的角色。发酵设备&#xff0c;作为这一技术的核心&#xff0c;不仅促进了抗生素、疫苗和生物药物的生产&#xff0c;还为酶的生物合成提供了必要的条件。 发酵技术是指人们利用微生物的发酵作用&#xff0c;通过一系列的…

HCIP快速生成树 RSTP

STP&#xff08;Spanning Tree Protocol&#xff0c;生成树协议&#xff09;和RSTP&#xff08;Rapid Spanning Tree Protocol&#xff0c;快速生成树协议&#xff09;都是用于在局域网中消除环路的网络协议。 STP&#xff08;生成树协议&#xff09; 基本概念&#xff1a; ST…

Excel 无法打开文件

Excel 无法打开文件 ‘新建 Microsoft Excel 工作表.xlsx",因为 文件格式或文件扩展名无效。请确定文件未损坏&#xff0c;并且文件扩展名与文件的格式匹配。 原因是卸载WPS之后&#xff0c;注册表未修改过来。 重新下载WPS&#xff0c;新建&#xff0c;xls工作表&#x…

【计算机网络】网络框架

一、网络协议和分层 1.理解协议 什么是协议&#xff1f;实际上就是约定。如果用计算机语言进行表达&#xff0c;那就是计算机协议。 2.理解分层 分层是软件设计方面的优势&#xff08;低耦合&#xff09;&#xff1b;每一层都要解决特定的问题 TCP/IP四层模型和OSI七层模型…

DPPE-N3中叠氮基团使得DPPE-N3能够与含有炔基的材料在铜离子的催化下发生点击化学反应,生成稳定的1,2,3-三唑环结构,2252461-33-7

一、基本信息 英文名称&#xff1a;DPPE-N3&#xff0c;DPPE-Azide 中文名称&#xff1a;DPPE-叠氮 CAS号&#xff1a;2252461-33-7 分子式&#xff1a;C43H83N4O9P 分子量&#xff1a;831.13 供应商&#xff1a;陕西新研博美生物科技 结构式&#xff1a; 二、结构特点…

算法学习第一弹——C++基础

早上好啊&#xff0c;大佬们。来看看咱们这回学点啥&#xff0c;在前不久刚出完C语言写的PTA中L1的题目&#xff0c;想必大家都不过瘾&#xff0c;感觉那些题都不过如此&#xff0c;所以&#xff0c;为了我们能更好的去处理更难的题目&#xff0c;小白兔决定奋发图强&#xff0…

[AcWing算法基础课]动态规划之01背包

题目链接&#xff1a;01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。第 i 件物品的体积是 vi&#xff0c;价值是 wi。求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。输出最大价值。 首先&#xff0c;我们…