当前位置: 首页 > news >正文

【代码随想录day33】【C++复健】62.不同路径;63. 不同路径 II;343. 整数拆分;96.不同的二叉搜索树

感觉dp的题真的很适合背,当然不是死记硬背,而是当做一种模板题,出来一道新的题就往模板题上面去靠,如果套对模板的话剩下的事情其实就简单了。所以只要看一遍解法知道大致思路其实就够了,毕竟大部分dp的代码也不算难写。

62.不同路径

先是使用二维dp数组的方法,结果发现二维数组的定义有点忘了,于是乱写了一个,没想到对了,就是vector<vector<int>> dp(m, vector<int>(n));

其他部分的话就没有太多好说的。

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n));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][j-1] + dp[i-1][j];}}return dp[m-1][n-1];}
};

然后重点说下这个一维的解法:
第一遍写的时候把i和j的顺序写反了,结果就是完全不对了。一开始觉得不就是遍历顺序从横着变成竖着嘛,有什么不一样的?

思考良久,发现是在定义这个dp数组的时候,我们把长度定义成了dp[n],而实际上每次循环经过的是m次,简单来说就是会把值存错位置,导致无法得到正确结果。

可以对比一下下面这两段代码:

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

这两段代码都是可以正确提交的,区别在于,当我们想要变更循环顺序的时候,需要把dp数组的定义和初始化也都相应的变一下,不然就会发生报错。

总结一下,就是dp数组长度要与内层循环相等,写出来之后我自己都吓了一跳,这么简单的道理我怎么就没想到呢。当我们要动态更新一个长度为n的数组的时候,当然是每次循环都把这n个数都更新一遍,然后重复m次才对嘛。

63. 不同路径 II

有了上一题的结论做基础,本题即使是一维数组,也必将一遍拿下... 吗?

写了一套看似没什么问题的代码,实际上却没法全过:

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

问题出在哪里了?我们在循环的时候,如果按上一题一样,实际上是默认每次循环的dp[0]都是等于1的,但是本题当中却不能做这样的假设,因为如果在某次循环的0号位有一个障碍物,从此时开始的dp[0]应该是0才对,而并不是1。这个时候我们就不能像上一题一样从i=1开始了,而是要从i=0开始,但是此时又出现了问题,i=0的是时候,dp[i-1]又变成非法访问了,所以要再加一个i>0的判断,最终的代码如下:

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

 验证一下上题的结论,用m也能通过:

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

最后就是,其实买你对这种比较难的题,其实没必要非得用一维dp数组的思路去想,思路上面会相对复杂。

343. 整数拆分

一周目其实已经做过这题,二周目试图复现思路,但漏了情况。

1 外层的max的含义:

dp[i]代表之前算出的乘积中最大的那个,后面的那个代表本次的新结果的乘积,两个比较之后取一个最大值,代表动态更新的最大乘积。

2 内层的max的含义:

j*dp[i-j]代表分j出来,并且拿剩下的继续拆分。因为dp[i-j]代表的是将i-j至少拆成2个值之后的最大乘积,保留i-j原本的值不进行拆分的情况并不在此列。因此我们此处还需要一个额外的max。

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

本题我就是漏了里面的max,以为只要写j*dp[i-j]即可,就错了。

还有就是我这么定义n+1的dp数组,一定要注意终止条件要设置成i <= n,否则就会出现dp[n]是0的情况(害我想半天)。

96.不同的二叉搜索树

本题其实是相当有难度的,一周目记得做到的时候毫无思路,但也因此这个题给我留下了深刻的印象,清楚地知道就是从i处对数组截断,两边取dp数组得到的值最后算个乘积,所以一遍就做出来了。

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

相关文章:

【代码随想录day33】【C++复健】62.不同路径;63. 不同路径 II;343. 整数拆分;96.不同的二叉搜索树

感觉dp的题真的很适合背&#xff0c;当然不是死记硬背&#xff0c;而是当做一种模板题&#xff0c;出来一道新的题就往模板题上面去靠&#xff0c;如果套对模板的话剩下的事情其实就简单了。所以只要看一遍解法知道大致思路其实就够了&#xff0c;毕竟大部分dp的代码也不算难写…...

《勇者斗恶龙3:HD-2D重制版》找幽灵船攻略分享

《勇者斗恶龙3&#xff1a;HD-2D重制版》中的幽灵船是游戏里非常独特的一个区域&#xff0c;而想要找到幽灵船的话还是比较麻烦的&#xff0c;首先是听到关于幽灵船在世界海域上航行的传闻&#xff0c;包括在海盗巢穴中&#xff0c;但幽灵船的出现有一些具体条件。 勇者斗恶龙3…...

基于 MATLAB 的模拟退火算法详解及实现

以下是一篇更详细的关于 模拟退火算法 (Simulated Annealing) 的 MATLAB 实现的教程和代码示例&#xff0c;涵盖基本概念、核心思想和代码实现。 一、模拟退火算法简介 模拟退火算法&#xff08;Simulated Annealing&#xff0c;简称 SA&#xff09;是一种随机优化算法&#x…...

MQTT 服务器常用的有哪些?

MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的消息传输协议&#xff0c;常用于物联网&#xff08;IoT&#xff09;设备之间的通信。以下是一些常用的 MQTT 服务器&#xff08;也称为 MQTT Broker&#xff09;&#xff1a; 1.Eclipse Mosqui…...

【android USB 串口通信助手】stm32 源码demo 单片机与手机通信 Android studio 20241118

android 【OTG线】 接 下位机STM32【USB】 通过百度网盘分享的文件&#xff1a;USBToSerialPort.apk 链接&#xff1a;https://pan.baidu.com/s/122McdmBDUxEtYiEKFunFUg?pwd8888 提取码&#xff1a;8888 android 【OTG线】 接 【USB转TTL】 接 【串口(下位机 SMT32等)】 需…...

汽车资讯新探索:Spring Boot技术引领

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了汽车资讯网站的开发全过程。通过分析汽车资讯网站管理的不足&#xff0c;创建了一个计算机管理汽车资讯网站的方案。文章介绍了汽车资讯网站的系统分析部分&…...

简单的MCU与FPGA通过APB总线实现通讯(fpga mcu APB):乘法器为例

测试平台: GW1N4器件内置 M1内核;并且可以设置 APB总线与fpga 逻辑进行交互; 框图: +---------------------+ | | | M1 Microprocessor | <-----------------+ | | | | +-----------------…...

css uniapp背景图宽度固定高度自适应可以重复

page {height: 100%;background-image: url(https://onlinekc.a.hlidc.cn/uploads/20241115/350f94aaf493d05625a7ddbc86c7804e.png);background-repeat: repeat;background-size: contain;} 如果不要重复 把background-repeat: repeat;替换background-repeat: no-repeat;...

深度学习--优化器

笔记内容侵权联系删 优化器 在梯度下降算法中&#xff0c;有各种不同的改进版本。在面向对象的语言实现中&#xff0c;往往把不同的梯度下降算法封装成一个对象&#xff0c;称为优化器。 算法改进的目的&#xff0c;包括但不限于: 加快算法收敛速度; 尽量避过或冲过局部极值; …...

【嵌入式】关于push老仓库到新仓库的方法

1. 背景 公司项目经常会有需要从开源项目中镜像代码过来的活,所以常常会在自己的服务器上创建一个对应的仓库,然后使用命令将期push过去。为方便日后抄命令,这里记录一下使用的命令。 2. 操作步骤 2.1. 已下载的代码push 特别提醒: 使用此脚本前请确保你修改的代码已保存…...

从线下到线上,上门洗衣服务如何实现智能化升级?

在现代快节奏生活的推动下&#xff0c;上门洗衣服务作为一种新兴的服务模式正逐渐崭露头角。它以其便捷性和创新性&#xff0c;改变了传统洗衣行业的格局&#xff0c;为消费者提供了全新的选择&#xff0c;同时也为洗衣品牌带来了新的机遇与挑战。 一、上门洗衣服务的市场现状1…...

SQL字段来源表的解析

测试例子&#xff1a; SELECT e.NAME, d.DEPT_NAME,d.DEPT_ID,EMP_ID,100EMP_ID100 FROM EMP e JOIN DEPT d ON e.DEPT_ID d.DEPT_ID WHERE e.EMP_ID IN (SELECT EMP_ID FROM EMP WHERE DEPT_ID 10) 代码示例&#xff1a; package com.test; import org.apache.calcite.jd…...

理解 Python 解释器:CPython 与 IPython 的比较及选择指南

理解 Python 解释器&#xff1a;CPython 与 IPython 的比较及选择指南 在选择适合自己需求的 Python 解释器时&#xff0c;理解 CPython 和 IPython 之间的主要差异至关重要。本文将详细解释 CPython 和 IPython 的特性、优势和适用场景&#xff0c;以帮助用户做出明智的选择。…...

Java NIO 深度解析:构建高效的 I/O 操作

在 Java 编程领域&#xff0c;I/O 操作一直是至关重要的部分&#xff0c;它直接影响着应用程序的性能和响应能力。Java NIO&#xff08;New I/O&#xff09;作为传统 I/O 的增强版本&#xff0c;为处理大量并发连接和高效的数据传输提供了更强大的工具和机制。本文将深入探讨 J…...

总结拓展十六:特殊采购业务——VMI采购模式

1、VMI的定义 VMI采购模式&#xff08;Vendor Managed Inventory&#xff09;是一种合作性策略&#xff0c;旨在通过供应商管理库存&#xff0c;使供应链中的企业和供应商双方都能获得最低成本。‌在这种模式下&#xff0c;供应商根据共享的用户企业库存和实际耗用数据&#x…...

vue2 + iview(view-design) 中封装使用 vxe-table 处理表格渲染大量数据卡顿现象

今天遇到需求&#xff0c;iview组件分页每页100页时候页面卡顿现象严重&#xff0c;改造为使用vxe-table cell-mouseenter"handleCellMouseEnter" cell-mouseleave"handleCellMouseLeave" 这两个用来处理vxe-table 内容过多鼠标悬浮上去滚动 tooltip直接…...

初学者指南:知识库问答(KBQA)多跳路径的核心与应用

初学者指南&#xff1a;知识库问答&#xff08;KBQA&#xff09;多跳路径的核心与应用 知识库问答&#xff08;Knowledge Base Question Answering, KBQA&#xff09;旨在利用结构化知识库&#xff08;如Wikidata、Freebase&#xff09;回答自然语言问题。在实际应用中&#x…...

创建springboot+vue项目相关配置问题

安装并配置jdk23 在官网下载jdk Java Downloads | Oracle 中国 下载完成后双击即可安装。 安装完成后配置环境变量 此电脑->右键->属性->高级系统设置 然后一直点击确定即可。 键盘上win r java -version 可以验证是否配置成功 下载并配置maven 在官网下…...

基于AOA算术优化的KNN数据聚类算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于AOA算术优化的KNN数据聚类算法matlab仿真。通过AOA优化算法&#xff0c;搜索最优的几个特征数据&#xff0c;进行KNN聚类&#xff0c;同时对比不同个数特征下…...

【机器学习】在泊松分布中,当λ值较大时,其近似正态分布的误差如何评估?

在泊松分布中&#xff0c;当参数 λ 较大时&#xff0c;其近似正态分布的有效性可以通过 中心极限定理 和误差分析来理解和评估。以下内容结合理论推导和实际案例展开说明&#xff1a; 1. 泊松分布的定义 泊松分布是用于建模单位时间或单位空间内随机事件发生次数的概率分布&a…...

突破PDF文字识别困境:Umi-OCR开源工具的全流程解决方案

突破PDF文字识别困境&#xff1a;Umi-OCR开源工具的全流程解决方案 【免费下载链接】Umi-OCR Umi-OCR: 这是一个免费、开源、可批量处理的离线OCR软件&#xff0c;适用于Windows系统&#xff0c;支持截图OCR、批量OCR、二维码识别等功能。 项目地址: https://gitcode.com/Git…...

ChatGPT公式复制到Word的自动化实践:从手动操作到脚本实现

ChatGPT公式复制到Word的自动化实践&#xff1a;从手动操作到脚本实现 作为一名经常需要整理技术文档的开发者&#xff0c;我过去常常被一个看似简单却异常繁琐的任务困扰&#xff1a;将ChatGPT生成的数学公式或代码片段复制到Microsoft Word中。每次操作都像是一场格式的“灾…...

零基础学习数据库:用快马AI生成你的第一个可操作图书管理系统

作为一个刚接触数据库的小白&#xff0c;最近在InsCode(快马)平台上尝试做了一个图书管理系统项目&#xff0c;整个过程意外地顺利。这里记录下我的学习心得&#xff0c;希望能帮到同样零基础的朋友们。 为什么选择图书管理系统作为入门项目 图书管理系统包含了数据库最基础的…...

星露谷物语模组加载器SMAPI终极指南:轻松安装与高效管理

星露谷物语模组加载器SMAPI终极指南&#xff1a;轻松安装与高效管理 【免费下载链接】SMAPI The modding API for Stardew Valley. 项目地址: https://gitcode.com/gh_mirrors/smap/SMAPI 想要让你的《星露谷物语》游戏体验焕然一新吗&#xff1f;SMAPI模组加载器就是你…...

FLUX小红书V2模型版本对比:V1与V2的核心改进与效果差异

FLUX小红书V2模型版本对比&#xff1a;V1与V2的核心改进与效果差异 1. 引言 如果你最近在玩AI图像生成&#xff0c;特别是想做出那种看起来特别真实、特别有小红书风格的照片&#xff0c;那你肯定听说过FLUX小红书模型。这个模型从V1版本开始就挺火的&#xff0c;主要是因为它…...

Qwen3-ASR-1.7B在C++项目中的集成与应用

Qwen3-ASR-1.7B在C项目中的集成与应用 1. 环境准备与快速部署 要在C项目中集成Qwen3-ASR-1.7B语音识别功能&#xff0c;首先需要准备好开发环境。这个模型虽然功能强大&#xff0c;但部署起来并不复杂&#xff0c;只需要几个简单的步骤。 系统要求&#xff1a; 操作系统&am…...

MediaPipe TouchDesigner GPU视觉插件实战:从零构建实时交互应用的完整指南

MediaPipe TouchDesigner GPU视觉插件实战&#xff1a;从零构建实时交互应用的完整指南 【免费下载链接】mediapipe-touchdesigner GPU Accelerated MediaPipe Plugin for TouchDesigner 项目地址: https://gitcode.com/gh_mirrors/me/mediapipe-touchdesigner 你是否厌…...

软件工程师如何转型AI工程师 第三章 技术路线的选择——不要从头学起

第三章 技术路线的选择——不要从头学起 在转型的技术路径上&#xff0c;我见过最多的弯路长这个样子&#xff1a;某个工程师下定决心要搞AI&#xff0c;于是买了一本《深度学习》&#xff08;花书&#xff09;&#xff0c;从第一章线性代数开始硬啃&#xff0c;啃到反向传播…...

Phi-4-Reasoning-Vision代码实例:TextIteratorStreamer实现思考过程智能分隔

Phi-4-Reasoning-Vision代码实例&#xff1a;TextIteratorStreamer实现思考过程智能分隔 1. 项目概述 Phi-4-Reasoning-Vision是基于微软Phi-4-reasoning-vision-15B多模态大模型开发的高性能推理工具&#xff0c;专为双卡RTX 4090环境优化。该工具严格遵循官方SYSTEM PROMPT…...

Realistic Vision V5.1 虚拟摄影棚面试实战:解析Java八股文中的系统设计题

Realistic Vision V5.1 虚拟摄影棚面试实战&#xff1a;解析Java八股文中的系统设计题 最近在帮朋友准备后端开发的面试&#xff0c;发现一个挺有意思的现象。大家聊起Java八股文&#xff0c;尤其是系统设计题&#xff0c;总觉得有点枯燥&#xff0c;像是在背标准答案。什么“…...