第四十一天 | 62.不同路径 63.不同路径|| 343.整数拆分 96.不同的二叉搜索树

题目:62.不同路径

1.二维dp数组dp[i][j]含义:到达(i,j)位置有dp[i][j]种方法。

2.动态转移方程:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

3.初始化:dp[0][j] = 1, dp[i][0] = 1 (第一行第一列都为1)

4.遍历顺序:从上向下,从左往右

5.打印dp

二维数组怎么定义?

代码如下:

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n, 0));for(int i = 0; i < m; i++){dp[i][0] = 1;}for(int j = 0; j < n; j++){dp[0][j] = 1;}for(int i = 1; i < m; i++){for(int j = 1; j < n; j++){dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m - 1][n - 1];}
};

题目:63.不同路径||

思路:

1.dp数组及含义:到达(i,j)位置有dp[i][j]种方法。

2.状态转移方程:dp[i][j] = dp[i - 1][j] + dp[i][j - 1](遇到空位置才进行计算)

3.初始化:dp[0][j] = 1, dp[i][0] = 1 (第一行第一列都为1)。当遇到障碍后停止。

4.遍历顺序:从上向下,从左往右

5.打印dp

代码如下:

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {vector<vector<int>> dp(obstacleGrid.size(), vector<int>(obstacleGrid[0].size(), 0));for(int i = 0; i < obstacleGrid.size() && obstacleGrid[i][0] == 0; i++){dp[i][0] = 1;}for(int j = 0; j < obstacleGrid[0].size() && obstacleGrid[0][j] == 0; j++){dp[0][j] = 1;}for(int i = 1; i < obstacleGrid.size(); i++){for(int j = 1; j <obstacleGrid[0].size(); j++){if(obstacleGrid[i][j] == 0){dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}}return dp[obstacleGrid.size() - 1][obstacleGrid[0].size() - 1];}
};

题目:343.整数拆分

关键在于理解递推公式。(考虑好有几个需要比较的情况)

什么时候乘积最大?拆成尽可能相等的数

思路:

1.dp含义:数i经过拆分后,得到最大的乘积dp[i]

2.状态转移方程(dp[i] 是依靠 dp[i - j]的状态):

递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

        1)有两种拆分方式:一是i * (i - j)直接相乘(把 i 拆成两个数);

                                    二是 j * dp[i - j](把 i 拆成三个数及以上)         

        2)在递推公式推导的过程中,每次计算dp[i],取最大的而已

                因为在第二层循环中会不断得到新的dp[i],用本轮for循环得到的dp[i]与之前得到的最大的dp[i]作比较,取更大的。

3.初始化:

拆分0和拆分1的最大乘积是多少?

这是无解的。

这里我只初始化dp[2] = 1,从dp[i]的定义来说,拆分数字2,得到的最大乘积是1,这个没有任何异议!确定遍历顺序,先来看看递归公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

4.确定遍历顺序:从前到后

确定遍历顺序,先来看看递归公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]。

5.打印dp数组:

class Solution {
public:int integerBreak(int n) {vector<int> dp(n + 1);dp[0] = 0;dp[1] = 0;dp[2] = 1;for(int i = 3; i <= n; i++){for(int j = 1; j <= i / 2; j++){dp[i] = max(max(j * (i - j), j * dp[i - j]), dp[i]);}}return dp[n];}
};

题目:96.不同的二叉搜索树

思路:

1.dp数组含义:含有 i 个节点的二叉搜索树共有dp[i]种

2.状态转移方程:

dp[3],就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点搜索树的数量

元素1为头结点搜索树的数量 = 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量

元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量

元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量

有2个元素的搜索树数量就是dp[2]。

有1个元素的搜索树数量就是dp[1]。

有0个元素的搜索树数量就是dp[0]。

所以dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2]

所以递推公式:dp[i] += dp[j - 1] * dp[i - j]; ,j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量

3.初始化:

初始化,只需要初始化dp[0]就可以了,推导的基础,都是dp[0]。

那么dp[0]应该是多少呢?

从定义上来讲,空节点也是一棵二叉树,也是一棵二叉搜索树,这是可以说得通的。

从递归公式上来讲,dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量] 中以j为头结点左子树节点数量为0,也需要dp[以j为头结点左子树节点数量] = 1, 否则乘法的结果就都变成0了。

4.遍历顺序:左往右

5.打印dp

容易犯得典型错误:

class Solution {
public:int numTrees(int n) {vector<int> dp(n + 1, 0);dp[0] = 1;      //易错:空二叉树也是二叉搜索树dp[1] = 1;dp[2] = 2;for(int i = 3; i <= n; i++){      //统计以1,2,...,n为结点有多少种不同的二叉树for(int j = 1; j <= i; j++){     //统计以1,2,...,i为头结点,同时共n个节点,有多少种不同的二叉树dp[i] += dp[j - 1] * dp[i - j]; }}return dp[n];}
};

在初始化时赋值dp[2]等于0,如果题目中n = 1,则会越界。

这一点很容易犯错

其实经常会有一个困惑,到底初始化时要初始前多少个呢?(手动模拟一下)

正确代码如下:

class Solution {
public:int integerBreak(int n) {vector<int> dp(n + 1);dp[0] = 0;for(int i = 1; i <= n; i++){for(int j = 1; j <= i / 2; j++){dp[i] = max(max(j * (i - j), j * dp[i - j]), dp[i]);}}return dp[n];}
};

其实只用定义dp[0] = 0,dp[1]往后都是可以动态规划循环推出来的。

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

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

相关文章

Spring Cloud 之 Gateway

本篇主要介绍有关Gateway网关的相关内容。 目录 一、什么是网关 二、Gateway的使用 Gateway服务的搭建 Route Predicate Factories Gateway Filter Factories Filter GlobalFilter Filter的执行顺序 一、什么是网关 经常面试的人肯定知道&#xff0c;在去公司面试时…

CAN笔记第二篇,车载测试继续学起来!

在CAN协议中&#xff0c;“帧”是一个包含完整信息的独立单元&#xff0c;它具有特定的格式和结构&#xff0c;以确保数据在CAN总线上的可靠传输。这里的“帧”字可以理解为&#xff1a; 完整性&#xff1a;一个帧包含了所有必要的信息&#xff0c;从起始到结束&#xff0c;都遵…

【LeetCode】【1】两数之和(1141字)

文章目录 [toc]题目描述样例输入输出与解释样例1样例2样例3 提示进阶Python实现哈希表 个人主页&#xff1a;丷从心 系列专栏&#xff1a;LeetCode 刷题指南&#xff1a;LeetCode刷题指南 题目描述 给定一个整数数组nums和一个整数目标值target&#xff0c;请在该数组中找出…

视觉检测实战项目——九点标定

本文介绍九点标定方法 已知 9 个点的图像坐标和对应的机械坐标,直接计算转换矩阵,核心原理即最小二乘拟合 {𝑥′=𝑎𝑥+𝑏𝑦+𝑐𝑦′=𝑎′𝑥+𝑏′𝑦+𝑐′ [𝑥1𝑦11𝑥2𝑦21⋮⋮⋮𝑥9𝑦91][𝑎𝑎′𝑏𝑏′𝑐𝑐′]=[𝑥1′𝑦…

AI爆文写作:根据别人的爆款标题,如何通过名词替换改成自己的爆款标题?

在日常刷到爆文的时候&#xff0c;就可以培养自己的网感&#xff0c;为啥这篇文章会爆&#xff1f; 这篇爆文的标题有啥诀窍呢&#xff1f; 比如下面这一篇&#xff1a;《极简生活&#xff1a;变富就是每天循环5个动作》 我们可以发现&#xff0c;每天循环5个动作 这几个词语…

C#基础一

使用Visual Studio 2022&#xff08;VS2022&#xff09;编写C#控制台程序 1. 安装Visual Studio 2022 确保已安装Visual Studio 2022。如果未安装&#xff0c;请从Visual Studio官网下载并安装。 另一篇文章中已经有详细描述&#xff0c;这里就不在细说了。 VisualStudio2022…

【JavaEE 初阶(十)】JVM

❣博主主页: 33的博客❣ ▶️文章专栏分类:JavaEE◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多进阶知识 目录 1.前言2.JVM内存区域划分3.类加载3.1双亲委派模型 4.垃圾回收&#xff08;GC&#xff0…

1098: 堆的判断

解法&#xff1a; 堆是完全二叉树 用数组来存储 然后用定义判定 #include<iostream> #include<vector> using namespace std; int main() {int n;cin >> n;vector<int> vec(n);for (int i 0; i < n; i) cin >> vec[i];for (int i 0; i &…

LabVIEW超高温高压流变仪测试系统

LabVIEW超高温高压流变仪测试系统 超高温高压流变仪广泛应用于石油、天然气、化工等行业&#xff0c;用于测量材料在极端条件下的流变特性。随着计算机技术、测试技术和电子仪器技术的快速发展&#xff0c;传统的流变仪测试方式已无法满足现代工业的需求。因此&#xff0c;开发…

【全开源】沃德商协会管理系统源码(FastAdmin+ThinkPHP+Uniapp)

一款基于FastAdminThinkPHPUniapp开发的商协会系统&#xff0c;新一代数字化商协会运营管理系统&#xff0c;以“智慧化会员体系、智敏化内容运营、智能化活动构建”三大板块为基点&#xff0c;实施功能全场景覆盖&#xff0c;一站式解决商协会需求壁垒&#xff0c;有效快速建立…

就业班 第三阶段(CICD) 2401--5.15 day2 自动化构建打包、部署(Jenkins + maven+ gitlab+tomcat)

一、平滑发布与灰度发布 **什么叫平滑&#xff1a;**在发布的过程中不影响用户的使用&#xff0c;系统不会因发布而暂停对外服务&#xff0c;不会造成用户短暂性无法访问&#xff1b; **什么叫灰度&#xff1a;**发布后让部分用户使用新版本&#xff0c;其它用户使用旧版本&am…

vector的底层实现与模拟

嗨喽大家好&#xff0c;时隔许久阿鑫又给大家带来了新的博客&#xff0c;关于vector的模拟实现&#xff0c;下面让我们开始今天的学习吧&#xff01; vector的底层实现与模拟 1.关于vector中的插入和删除 2. vector中的拷贝构造和赋值 3.vector的构造函数 4.关于vector中浅…

微信小程序报错:notifyBLECharacteristicValueChange:fail:nodescriptor的解决办法

文章目录 一、发现问题二、分析问题二、解决问题 一、发现问题 微信小程序报错&#xff1a;notifyBLECharacteristicValueChange:fail:nodescriptor 二、分析问题 这个提示有点问题&#xff0c;应该是该Characteristic的Descriptor有问题&#xff0c;而不能说nodescriptor。 …

windows docker desktop 更换镜像存储目录

windows docker desktop 更换镜像存储目录 方法&#xff1a;如图&#xff0c;Browse浏览一个新的目录并选中&#xff0c;确定后&#xff0c;程序会开始stop&#xff0c;在stop完成前&#xff0c;会持续迁移原有镜像到新的位置&#xff0c;你会发现目标位置的磁盘占用空间越来越…

DNS服务的部署与配置(1)

一、DNS的定义 1、域名系统&#xff08;英文&#xff1a;Domain Name System&#xff0c;缩写&#xff1a;DNS&#xff09;是互联网的一项服务。 它作为将域名和IP地址相互映射的一个分布式数据库&#xff0c;能够使人更方便地访问互联网。 DNS使用UDP端口53。 当前&#xff0…

使用pygame绘制图形

参考链接&#xff1a;https://www.geeksforgeeks.org/pygame-tutorial/?reflbp 在窗口中绘制单个图形 import pygame from pygame.locals import * import sys pygame.init()window pygame.display.set_mode((600,600)) window.fill((255,255,255))# pygame.draw.rect(wind…

WSL调用docker

WSL&#xff08;windows subsystem linux&#xff09;是window系统的原生linux子系统&#xff0c;用于代码开发很方便。 希望在wsl里面运行docker&#xff0c;首先要安装docker在WSL中使用&#xff0c;大部分人的第一想法肯定是用以下命令行安装&#xff08;个人不推荐&#x…

【C语言】指针运算

前言 前面在“走进指针世界”中我已经讲解过指针相关的很多前置知识&#xff0c;其实还有一个很重要的部分就是指针的运算。这篇博客&#xff0c;就让我们一起了解一下指针的运算吧&#xff01; 指针作为变量&#xff0c;是可以进行算术运算的&#xff0c;只不过情况会和整型…

Behind the Code:Polkadot 如何重塑 Web3 未来

2024 年 5 月 17 日 Polkadot 生态 Behind the Code 第二季第一集 《创造 Web3 的未来》正式上线。第一集深入探讨了 Polkadot 和 Web3 技术在解决数字身份、数据所有权和去中心化治理方面的巨大潜力。 &#x1f50d; 查看完整视频&#xff1a; https://youtu.be/_gP-M5nUidc?…

aws glue配置读取本地kafka数据源

创建连接时填写本地私有ip地址&#xff0c;选择网络配置 配置任务选择kafka作为数据源 但是执行任务时日志显示连接失败 文档提到只能用加密通信 如果您希望与 Kafka 数据源建立安全连接&#xff0c;请选择 Require SSL connection (需要 SSL 连接)&#xff0c;并在 Kafka priv…